65 for (
const auto *nd : indirectField->
chain()) {
66 auto *fd = cast<clang::FieldDecl>(nd);
80 "Must have member initializer!");
81 assert(memberInit->
getInit() &&
"Must have initializer!");
114 "emitMemberInitializer: array of non-record type");
131struct DynamicThisUseChecker
135 bool usesThis =
false;
137 DynamicThisUseChecker(
const ASTContext &
c) : super(
c) {}
144 void VisitCXXThisExpr(
const CXXThisExpr *e) { usesThis =
true; }
149 DynamicThisUseChecker checker(
c);
151 return checker.usesThis;
181 assert(
curFuncDecl &&
"loading 'this' without a func declaration?");
202 loc, thisPtr, classDecl, baseClassDecl, isBaseVirtual);
232 bool constructVBases = ctorType !=
Ctor_Base &&
235 if (constructVBases &&
238 "emitCtorPrologue: virtual base without variants");
243 auto allInits = cd->
inits();
246 auto virtualBaseEnd = std::find_if(
248 return !(Init->isBaseInitializer() && Init->isBaseVirtual());
251 auto nonVirtualBaseEnd = std::find_if(virtualBaseEnd, allInits.end(),
253 return !Init->isBaseInitializer();
257 auto virtualBaseInits = llvm::make_range(allInits.begin(), virtualBaseEnd);
258 auto nonVirtualBaseInits =
259 llvm::make_range(virtualBaseEnd, nonVirtualBaseEnd);
260 auto memberInits = llvm::make_range(nonVirtualBaseEnd, allInits.end());
271 "emitCtorPrologue: strict vtable pointers for vbase");
278 if (!constructVBases)
280 emitInitializer(virtualBaseInit);
287 assert(!nonVirtualBaseInit->isBaseVirtual());
288 emitInitializer(nonVirtualBaseInit);
303 assert(!member->isBaseInitializer());
304 assert(member->isAnyMemberInitializer() &&
305 "Delegating initializer on non-delegating constructor");
312 CharUnits nonVirtualOffset, mlir::Value virtualOffset,
314 mlir::Type baseValueTy = {},
bool assumeNotNull =
true) {
316 assert(!nonVirtualOffset.
isZero() || virtualOffset !=
nullptr);
319 if (!nonVirtualOffset.
isZero()) {
323 "applyNonVirtualAndVirtualOffset: virtual and non-virtual offset");
326 assert(baseValueTy &&
"expected base type");
329 loc, addr, baseValueTy, nonVirtualOffset.
getQuantity(),
334 cgf.
cgm.
errorNYI(loc,
"applyNonVirtualAndVirtualOffset: virtual offset");
341 mlir::Value vtableAddressPoint =
345 if (!vtableAddressPoint)
349 mlir::Value virtualOffset{};
352 mlir::Type baseValueTy;
354 cgm.
errorNYI(loc,
"initializeVTablePointer: virtual offset for vtable");
364 if (!nonVirtualOffset.
isZero() || virtualOffset) {
366 loc, *
this, classAddr, nonVirtualOffset, virtualOffset,
375 auto vtablePtr = cir::VTableGetVPtrOp::create(
378 builder.
createStore(loc, vtableAddressPoint, vtableField);
405 false, vtableClass, vbases,
413 bool baseIsNonVirtualPrimaryBase,
419 if (!baseIsNonVirtualPrimaryBase) {
421 VPtr vptr = {base, nearestVBase, offsetFromNearestVBase, vtableClass};
422 vptrs.push_back(vptr);
427 for (
const auto &nextBase : rd->
bases()) {
428 const auto *baseDecl =
434 if (!baseDecl->isDynamicClass())
439 bool baseDeclIsNonVirtualPrimaryBase;
442 if (nextBase.isVirtual()) {
444 if (!vbases.insert(baseDecl).second)
450 nextBaseDecl = nearestVBase;
453 baseDeclIsNonVirtualPrimaryBase =
false;
457 nextBaseDecl = baseDecl;
459 baseOffsetFromNearestVBase =
461 baseDeclIsNonVirtualPrimaryBase = layout.
getPrimaryBase() == baseDecl;
465 baseOffsetFromNearestVBase,
466 baseDeclIsNonVirtualPrimaryBase, vtableClass, vbases,
472 assert(
curFuncDecl &&
"loading 'this' without a func declaration?");
480 auto rd = cast<CXXMethodDecl>(
curFuncDecl)->getParent();
496 "emitInitializerForField: non-simple scalar");
525 bool zeroInitialize) {
529 newPointerIsChecked, zeroInitialize);
551 if (
auto constantCount = numElements.getDefiningOp<cir::ConstantOp>()) {
552 if (
auto constIntAttr = constantCount.getValueAttr<cir::IntAttr>()) {
554 if (constIntAttr.getUInt() == 0)
559 if (constantCount.use_empty())
560 constantCount.erase();
566 auto arrayTy = mlir::cast<cir::ArrayType>(arrayBase.
getElementType());
567 mlir::Type elementType = arrayTy.getElementType();
568 cir::PointerType ptrToElmType = builder.
getPointerTo(elementType);
605 mlir::Value arrayOp =
607 builder.create<cir::ArrayCtor>(
608 *
currSrcLoc, arrayOp, [&](mlir::OpBuilder &
b, mlir::Location loc) {
609 mlir::BlockArgument arg =
610 b.getInsertionBlock()->addArgument(ptrToElmType, loc);
620 builder.create<cir::YieldOp>(loc);
630 FunctionArgList::const_iterator i = args.begin(), e = args.end();
631 assert(i != e &&
"no parameters to constructor");
641 cgm.
errorNYI(loc,
"emitDelegateCXXConstructorCall: VTT parameter");
646 for (; i != e; ++i) {
655 true, thisAddr, delegateArgs, loc);
659 const auto *assignOp = cast<CXXMethodDecl>(
curGD.
getDecl());
660 assert(assignOp->isCopyAssignmentOperator() ||
661 assignOp->isMoveAssignmentOperator());
662 const Stmt *rootS = assignOp->getBody();
663 assert(isa<CompoundStmt>(rootS) &&
664 "Body of an implicit assignment operator should be compound stmt.");
665 const auto *rootCS = cast<CompoundStmt>(rootS);
676 for (
Stmt *
s : rootCS->body())
679 std::string(
"emitImplicitAssignmentOperatorBody: ") +
680 s->getStmtClassName());
685 const auto *record =
type->castAsCXXRecordDecl();
713 "emitDelegatingCXXConstructorCall: exception");
720 bool forVirtualBase,
bool delegating,
723 delegating, thisAddr, thisTy);
728 llvm::iterator_range<CastExpr::path_const_iterator> path,
730 assert(!path.empty() &&
"Base path should not be empty!");
732 if ((*path.begin())->isVirtual()) {
735 cgm.
errorNYI(loc,
"getAddrOfBaseClass: virtual base");
746 mlir::Type baseValueTy =
convertType((path.end()[-1])->getType());
753 if (nonVirtualOffset.
isZero()) {
788 auto vtablePtr = cir::VTableGetVPtrOp::create(
792 auto vtable = builder.
createLoad(loc, vtablePtrAddr);
849 bool passPrototypeArgs =
true;
854 "emitCXXConstructorCall: inherited constructor");
864 args, d,
type, passPrototypeArgs);
866 cir::CIRCallOpInterface
c;
static bool baseInitializerUsesThis(ASTContext &c, const Expr *init)
static Address applyNonVirtualAndVirtualOffset(mlir::Location loc, CIRGenFunction &cgf, Address addr, CharUnits nonVirtualOffset, mlir::Value virtualOffset, const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase, mlir::Type baseValueTy={}, bool assumeNotNull=true)
static void emitMemberInitializer(CIRGenFunction &cgf, const CXXRecordDecl *classDecl, CXXCtorInitializer *memberInit, const CXXConstructorDecl *constructor, FunctionArgList &args)
static bool isInitializerOfDynamicClass(const CXXCtorInitializer *baseInit)
static void emitLValueForAnyFieldInitialization(CIRGenFunction &cgf, CXXCtorInitializer *memberInit, LValue &lhs)
Defines the clang::Expr interface and subclasses for C++ expressions.
C Language Family Type Representation.
__device__ __2f16 float __ockl_bool s
__device__ __2f16 float c
cir::PointerType getPointerTo(mlir::Type ty)
mlir::Value createPtrBitcast(mlir::Value src, mlir::Type newPointeeTy)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
CanQualType getCanonicalTagType(const TagDecl *TD) const
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
mlir::Value getPointer() const
mlir::Type getElementType() const
Address withElementType(CIRGenBuilderTy &builder, mlir::Type ElemTy) const
Return address with different element type, a bitcast pointer, and the same alignment.
clang::CharUnits getAlignment() const
static AggValueSlot forAddr(Address addr, clang::Qualifiers quals, IsDestructed_t isDestructed, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed)
Address getAddress() const
Address createBaseClassAddr(mlir::Location loc, Address addr, mlir::Type destType, unsigned offset, bool assumeNotNull)
mlir::Type getPtrToVPtrType()
cir::LoadOp createLoad(mlir::Location loc, Address addr, bool isVolatile=false)
cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst, bool isVolatile=false, mlir::IntegerAttr align={}, cir::MemOrderAttr order={})
virtual bool needsVTTParameter(clang::GlobalDecl gd)
Return whether the given global decl needs a VTT (virtual table table) parameter.
virtual mlir::Value getVTableAddressPointInStructor(CIRGenFunction &cgf, const CXXRecordDecl *vtableClass, BaseSubobject base, const CXXRecordDecl *nearestVBase)=0
Get the address point of the vtable for the given base subobject while building a constructor or a de...
virtual void emitDestructorCall(CIRGenFunction &cgf, const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)=0
virtual void initializeHiddenVirtualInheritanceMembers(CIRGenFunction &cgf, const CXXRecordDecl *rd)
Emit the code to initialize hidden members required to handle virtual inheritance,...
virtual bool isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf, CIRGenFunction::VPtr vptr)=0
Checks if ABI requires extra virtual offset for vtable field.
virtual bool doStructorsInitializeVPtrs(const clang::CXXRecordDecl *vtableClass)=0
Checks if ABI requires to initialize vptrs for given dynamic class.
static CIRGenCallee forDirect(mlir::Operation *funcPtr, const CIRGenCalleeInfo &abstractInfo=CIRGenCalleeInfo())
A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...
static bool isConstructorDelegationValid(const clang::CXXConstructorDecl *ctor)
Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...
void emitCallArgs(CallArgList &args, PrototypeWrapper prototype, llvm::iterator_range< clang::CallExpr::const_arg_iterator > argRange, AbstractCallee callee=AbstractCallee(), unsigned paramsToSkip=0)
mlir::Type convertType(clang::QualType t)
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...
const clang::LangOptions & getLangOpts() const
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...
clang::CharUnits cxxThisAlignment
const clang::Decl * curFuncDecl
Address loadCXXThisAddress()
LValue makeNaturalAlignAddrLValue(mlir::Value val, QualType ty)
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)
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)
void emitDelegateCXXConstructorCall(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, const FunctionArgList &args, clang::SourceLocation loc)
void emitBaseInitializer(mlir::Location loc, const CXXRecordDecl *classDecl, CXXCtorInitializer *baseInit)
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.
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)
VPtrsVector getVTablePointers(const clang::CXXRecordDecl *vtableClass)
void emitImplicitAssignmentOperatorBody(FunctionArgList &args)
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...
static Destroyer destroyCXXObject
void emitCXXConstructorCall(const clang::CXXConstructorDecl *d, clang::CXXCtorType type, bool forVirtualBase, bool delegating, AggValueSlot thisAVS, const clang::CXXConstructExpr *e)
mlir::Value getVTablePtr(mlir::Location loc, Address thisAddr, const clang::CXXRecordDecl *vtableClass)
Return the Value of the vtable pointer member pointed to by thisAddr.
bool shouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *rd)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
RValue emitCall(const CIRGenFunctionInfo &funcInfo, const CIRGenCallee &callee, ReturnValueSlot returnValue, const CallArgList &args, cir::CIRCallOpInterface *callOp, mlir::Location loc)
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...
void emitInitializerForField(clang::FieldDecl *field, LValue lhs, clang::Expr *init)
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.
CIRGenBuilderTy & getBuilder()
AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *rd, const CXXRecordDecl *baseRD, bool isVirtual)
Determine whether a base class initialization may overlap some other object.
void emitCXXDestructorCall(const CXXDestructorDecl *dd, CXXDtorType type, bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy)
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 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.
std::optional< mlir::Location > currSrcLoc
Use to track source locations across nested visitor traversals.
clang::ASTContext & getContext() const
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
void emitDelegatingCXXConstructorCall(const CXXConstructorDecl *ctor, const FunctionArgList &args)
void emitAggExpr(const clang::Expr *e, AggValueSlot slot)
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *derivedClass, llvm::iterator_range< CastExpr::path_const_iterator > path)
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
cir::FuncOp getAddrOfCXXStructor(clang::GlobalDecl gd, const CIRGenFunctionInfo *fnInfo=nullptr, cir::FuncType fnType=nullptr, bool dontDefer=false, ForDefinition_t isForDefinition=NotForDefinition)
clang::CharUnits getClassPointerAlignment(const clang::CXXRecordDecl *rd)
Return the best known alignment for an unknown pointer to a particular class.
const clang::TargetInfo & getTarget() const
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
CIRGenCXXABI & getCXXABI() const
const CIRGenFunctionInfo & arrangeCXXConstructorCall(const CallArgList &args, const clang::CXXConstructorDecl *d, clang::CXXCtorType ctorKind, bool passProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
void add(RValue rvalue, clang::QualType type)
Type for representing both the decl and type of parameters to a function.
static RValue get(mlir::Value v)
Contains the address where the return value of a function can be stored, and whether the address is v...
Represents a call to a C++ constructor.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Represents a C++ constructor within a class.
init_iterator init_begin()
Retrieve an iterator to the first initializer.
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
Represents a C++ base or member initializer.
Expr * getInit() const
Get the initializer.
SourceRange getSourceRange() const LLVM_READONLY
Determine the source range covering the entire initializer.
bool isAnyMemberInitializer() const
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
bool isIndirectMemberInitializer() const
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
FieldDecl * getAnyMember() const
IndirectFieldDecl * getIndirectMember() const
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Represents a C++ destructor within a class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
Represents a C++ struct/union/class.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
CXXRecordDecl * getDefinitionOrSelf() const
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Represents the this expression in C++.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isDefaulted() const
Whether this function is defaulted.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Represents a prototype with parameter type info, e.g.
bool isVariadic() const
Whether this function prototype is variadic.
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
const Decl * getDecl() const
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
A (possibly-)qualified type.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
The collection of all-type qualifiers we support.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() const
Encodes a location in the source.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
The base class of the type hierarchy.
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
bool isRecordType() const
Represents a variable declaration or definition.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
The JSON file list parser is used to communicate input to InstallAPI.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
CXXDtorType
C++ destructor types.
@ Dtor_Complete
Complete object dtor.
static bool implicitConstructorArgs()
static bool addressSpace()
static bool aggValueSlotGC()
static bool isMemcpyEquivalentSpecialMember()
static bool hiddenVisibility()
static bool runCleanupsScope()
static bool opCallArgEvaluationOrder()
static bool createInvariantGroup()
static bool isTrivialCtorOrDtor()
static bool assignMemcpyizer()
static bool ctorMemcpyizer()
static bool requiresCleanups()
static bool generateDebugInfo()
static bool incrementProfileCounter()
const clang::CXXRecordDecl * vtableClass
const clang::CXXRecordDecl * nearestVBase
clang::BaseSubobject base