diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenFunction.h')
| -rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.h | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 064b3c15a310..42f7f401555c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -25,7 +25,9 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/BaseSubobject.h" #include "clang/AST/CharUnits.h" +#include "clang/AST/CurrentSourceLocExprScope.h" #include "clang/AST/Decl.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/Stmt.h" #include "clang/AST/Type.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" @@ -64,6 +66,10 @@ public: /// The compiler-generated variable that holds the return value. std::optional<mlir::Value> fnRetAlloca; + /// The temporary alloca to hold the return value. This is + /// invalid iff the function has no return value. + Address returnValue = Address::invalid(); + /// Tracks function scope overall cleanup handling. EHScopeStack ehStack; @@ -74,6 +80,11 @@ public: mlir::Value cxxThisValue = nullptr; clang::CharUnits cxxThisAlignment; + /// When generating code for a constructor or destructor, this will hold the + /// implicit argument (e.g. VTT). + ImplicitParamDecl *cxxStructorImplicitParamDecl{}; + mlir::Value cxxStructorImplicitParamValue{}; + /// The value of 'this' to sue when evaluating CXXDefaultInitExprs within this /// expression. Address cxxDefaultInitExprThis = Address::invalid(); @@ -574,6 +585,9 @@ public: const clang::CXXRecordDecl *vtableClass; }; + using VisitedVirtualBasesSetTy = + llvm::SmallPtrSet<const clang::CXXRecordDecl *, 4>; + using VPtrsVector = llvm::SmallVector<VPtr, 4>; VPtrsVector getVTablePointers(const clang::CXXRecordDecl *vtableClass); void getVTablePointers(clang::BaseSubobject base, @@ -581,7 +595,7 @@ public: clang::CharUnits offsetFromNearestVBase, bool baseIsNonVirtualPrimaryBase, const clang::CXXRecordDecl *vtableClass, - VPtrsVector &vptrs); + VisitedVirtualBasesSetTy &vbases, VPtrsVector &vptrs); /// Return the Value of the vtable pointer member pointed to by thisAddr. mlir::Value getVTablePtr(mlir::Location loc, Address thisAddr, const clang::CXXRecordDecl *vtableClass); @@ -591,6 +605,12 @@ public: /// true when both vcall CFI and whole-program-vtables are enabled. bool shouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *rd); + /// Source location information about the default argument or member + /// initializer expression we're evaluating, if any. + clang::CurrentSourceLocExprScope curSourceLocExprScope; + using SourceLocExprScopeGuard = + clang::CurrentSourceLocExprScope::SourceLocExprScopeGuard; + /// A scope within which we are constructing the fields of an object which /// might use a CXXDefaultInitExpr. This stashes away a 'this' value to use if /// we need to evaluate the CXXDefaultInitExpr within the evaluation. @@ -609,6 +629,29 @@ public: Address oldCXXDefaultInitExprThis; }; + /// The scope of a CXXDefaultInitExpr. Within this scope, the value of 'this' + /// is overridden to be the object under construction. + class CXXDefaultInitExprScope { + public: + CXXDefaultInitExprScope(CIRGenFunction &cgf, const CXXDefaultInitExpr *e) + : cgf{cgf}, oldCXXThisValue(cgf.cxxThisValue), + oldCXXThisAlignment(cgf.cxxThisAlignment), + sourceLocScope(e, cgf.curSourceLocExprScope) { + cgf.cxxThisValue = cgf.cxxDefaultInitExprThis.getPointer(); + cgf.cxxThisAlignment = cgf.cxxDefaultInitExprThis.getAlignment(); + } + ~CXXDefaultInitExprScope() { + cgf.cxxThisValue = oldCXXThisValue; + cgf.cxxThisAlignment = oldCXXThisAlignment; + } + + public: + CIRGenFunction &cgf; + mlir::Value oldCXXThisValue; + clang::CharUnits oldCXXThisAlignment; + SourceLocExprScopeGuard sourceLocScope; + }; + LValue makeNaturalAlignPointeeAddrLValue(mlir::Value v, clang::QualType t); LValue makeNaturalAlignAddrLValue(mlir::Value val, QualType ty); @@ -630,6 +673,13 @@ public: llvm::iterator_range<CastExpr::path_const_iterator> path, bool nullCheckValue, SourceLocation loc); + /// Return the VTT parameter that should be passed to a base + /// constructor/destructor with virtual bases. + /// FIXME: VTTs are Itanium ABI-specific, so the definition should move + /// to ItaniumCXXABI.cpp together with all the references to VTT. + mlir::Value getVTTParameter(GlobalDecl gd, bool forVirtualBase, + bool delegating); + LValue makeAddrLValue(Address addr, QualType ty, AlignmentSource source = AlignmentSource::Type) { return makeAddrLValue(addr, ty, LValueBaseInfo(source)); @@ -643,6 +693,8 @@ public: const clang::CXXRecordDecl *rd); void initializeVTablePointer(mlir::Location loc, const VPtr &vptr); + AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *fd); + /// Return the address of a local variable. Address getAddrOfLocalVar(const clang::VarDecl *vd) { auto it = localDeclMap.find(vd); @@ -663,6 +715,14 @@ public: } Address loadCXXThisAddress(); + /// Load the VTT parameter to base constructors/destructors have virtual + /// bases. FIXME: Every place that calls LoadCXXVTT is something that needs to + /// be abstracted properly. + mlir::Value loadCXXVTT() { + assert(cxxStructorImplicitParamValue && "no VTT value for this function"); + return cxxStructorImplicitParamValue; + } + /// Convert the given pointer to a complete class to the given direct base. Address getAddressOfDirectBaseInCompleteClass(mlir::Location loc, Address value, @@ -670,6 +730,14 @@ public: const CXXRecordDecl *base, bool baseIsVirtual); + /// Determine whether a return value slot may overlap some other object. + AggValueSlot::Overlap_t getOverlapForReturnValue() { + // FIXME: Assuming no overlap here breaks guaranteed copy elision for base + // class subobjects. These cases may need to be revisited depending on the + // resolution of the relevant core issue. + return AggValueSlot::DoesNotOverlap; + } + /// Determine whether a base class initialization may overlap some other /// object. AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *rd, @@ -962,6 +1030,16 @@ public: LValue emitAggExprToLValue(const Expr *e); + /// Emit an aggregate copy. + /// + /// \param isVolatile \c true iff either the source or the destination is + /// volatile. + /// \param MayOverlap Whether the tail padding of the destination might be + /// occupied by some other object. More efficient code can often be + /// generated if not. + void emitAggregateCopy(LValue dest, LValue src, QualType eltTy, + AggValueSlot::Overlap_t mayOverlap); + /// Emit code to compute the specified expression which can have any type. The /// result is returned as an RValue struct. If this is an aggregate /// expression, the aggloc/agglocvolatile arguments indicate where the result @@ -1140,6 +1218,8 @@ public: RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr); + void emitCXXThrowExpr(const CXXThrowExpr *e); + void emitCtorPrologue(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, FunctionArgList &args); @@ -1287,6 +1367,8 @@ public: /// the LLVM value representation. The l-value must be a simple /// l-value. mlir::Value emitLoadOfScalar(LValue lvalue, SourceLocation loc); + mlir::Value emitLoadOfScalar(Address addr, bool isVolatile, QualType ty, + SourceLocation loc, LValueBaseInfo baseInfo); /// Emit code to compute a designator that specifies the location /// of the expression. |
