summaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen/CIRGenFunction.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenFunction.h')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenFunction.h84
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.