Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,8 @@ struct MissingFeatures {
// RecordType
static bool skippedLayout() { return false; }
static bool astRecordDeclAttr() { return false; }
static bool cxxSupport() { return false; }
static bool recordZeroInit() { return false; }
static bool zeroSizeRecordMembers() { return false; }
static bool recordLayoutVirtualBases() { return false; }

// Various handling of deferred processing in CIRGenModule.
static bool cgmRelease() { return false; }
Expand All @@ -148,7 +146,6 @@ struct MissingFeatures {
static bool cxxabiUseARMMethodPtrABI() { return false; }
static bool cxxabiUseARMGuardVarABI() { return false; }
static bool cxxabiAppleARM64CXXABI() { return false; }
static bool cxxabiStructorImplicitParam() { return false; }
static bool isDiscreteBitFieldABI() { return false; }

// Address class
Expand Down Expand Up @@ -229,7 +226,6 @@ struct MissingFeatures {
static bool globalViewIndices() { return false; }
static bool globalViewIntLowering() { return false; }
static bool hip() { return false; }
static bool implicitConstructorArgs() { return false; }
static bool incrementProfileCounter() { return false; }
static bool innermostEHScope() { return false; }
static bool insertBuiltinUnpredictable() { return false; }
Expand Down
33 changes: 33 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,10 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
cir::ConstantOp getUInt32(uint32_t c, mlir::Location loc) {
return getConstantInt(loc, getUInt32Ty(), c);
}
cir::ConstantOp getSInt64(uint64_t c, mlir::Location loc) {
cir::IntType sInt64Ty = getSInt64Ty();
return cir::ConstantOp::create(*this, loc, cir::IntAttr::get(sInt64Ty, c));
}

// Creates constant nullptr for pointer type ty.
cir::ConstantOp getNullPtr(mlir::Type ty, mlir::Location loc) {
Expand Down Expand Up @@ -359,6 +363,18 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
return Address(baseAddr, destType, addr.getAlignment());
}

mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy,
mlir::Value addr, uint64_t offset) {
return cir::VTTAddrPointOp::create(*this, loc, retTy,
mlir::FlatSymbolRefAttr{}, addr, offset);
}

mlir::Value createVTTAddrPoint(mlir::Location loc, mlir::Type retTy,
mlir::FlatSymbolRefAttr sym, uint64_t offset) {
return cir::VTTAddrPointOp::create(*this, loc, retTy, sym, mlir::Value{},
offset);
}

/// Cast the element type of the given address to a different type,
/// preserving information like the alignment.
Address createElementBitCast(mlir::Location loc, Address addr,
Expand All @@ -379,6 +395,23 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
/*mem_order=*/cir::MemOrderAttr{});
}

cir::LoadOp createAlignedLoad(mlir::Location loc, mlir::Type ty,
mlir::Value ptr, llvm::MaybeAlign align) {
if (ty != mlir::cast<cir::PointerType>(ptr.getType()).getPointee())
ptr = createPtrBitcast(ptr, ty);
uint64_t alignment = align ? align->value() : 0;
mlir::IntegerAttr alignAttr = getAlignmentAttr(alignment);
return cir::LoadOp::create(*this, loc, ptr, /*isDeref=*/false,
/*isVolatile=*/false, alignAttr,
/*mem_order=*/cir::MemOrderAttr{});
}

cir::LoadOp
createAlignedLoad(mlir::Location loc, mlir::Type ty, mlir::Value ptr,
clang::CharUnits align = clang::CharUnits::One()) {
return createAlignedLoad(loc, ty, ptr, align.getAsAlign());
}

cir::StoreOp createStore(mlir::Location loc, mlir::Value val, Address dst,
bool isVolatile = false,
mlir::IntegerAttr align = {},
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ using namespace clang::CIRGen;

CIRGenCXXABI::~CIRGenCXXABI() {}

CIRGenCXXABI::AddedStructorArgCounts CIRGenCXXABI::addImplicitConstructorArgs(
CIRGenFunction &cgf, const CXXConstructorDecl *d, CXXCtorType type,
bool forVirtualBase, bool delegating, CallArgList &args) {
AddedStructorArgs addedArgs =
getImplicitConstructorArgs(cgf, d, type, forVirtualBase, delegating);
for (auto [idx, prefixArg] : llvm::enumerate(addedArgs.prefix))
args.insert(args.begin() + 1 + idx,
CallArg(RValue::get(prefixArg.value), prefixArg.type));
for (const auto &arg : addedArgs.suffix)
args.add(RValue::get(arg.value), arg.type);
return AddedStructorArgCounts(addedArgs.prefix.size(),
addedArgs.suffix.size());
}

void CIRGenCXXABI::buildThisParam(CIRGenFunction &cgf,
FunctionArgList &params) {
const auto *md = cast<CXXMethodDecl>(cgf.curGD.getDecl());
Expand Down
79 changes: 79 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenCXXABI.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,67 @@ class CIRGenCXXABI {
/// constructor/destructor Decl.
virtual void emitCXXStructor(clang::GlobalDecl gd) = 0;

virtual mlir::Value
getVirtualBaseClassOffset(mlir::Location loc, CIRGenFunction &cgf,
Address thisAddr, const CXXRecordDecl *classDecl,
const CXXRecordDecl *baseClassDecl) = 0;

public:
/// Similar to AddedStructorArgs, but only notes the number of additional
/// arguments.
struct AddedStructorArgCounts {
unsigned prefix = 0;
unsigned suffix = 0;
AddedStructorArgCounts() = default;
AddedStructorArgCounts(unsigned p, unsigned s) : prefix(p), suffix(s) {}
static AddedStructorArgCounts withPrefix(unsigned n) { return {n, 0}; }
static AddedStructorArgCounts withSuffix(unsigned n) { return {0, n}; }
};

/// Additional implicit arguments to add to the beginning (Prefix) and end
/// (Suffix) of a constructor / destructor arg list.
///
/// Note that Prefix should actually be inserted *after* the first existing
/// arg; `this` arguments always come first.
struct AddedStructorArgs {
struct Arg {
mlir::Value value;
QualType type;
};
llvm::SmallVector<Arg, 1> prefix;
llvm::SmallVector<Arg, 1> suffix;
AddedStructorArgs() = default;
AddedStructorArgs(llvm::SmallVector<Arg, 1> p, llvm::SmallVector<Arg, 1> s)
: prefix(std::move(p)), suffix(std::move(s)) {}
static AddedStructorArgs withPrefix(llvm::SmallVector<Arg, 1> args) {
return {std::move(args), {}};
}
static AddedStructorArgs withSuffix(llvm::SmallVector<Arg, 1> args) {
return {{}, std::move(args)};
}
};

/// Build the signature of the given constructor or destructor vairant by
/// adding any required parameters. For convenience, ArgTys has been
/// initialized with the type of 'this'.
virtual AddedStructorArgCounts
buildStructorSignature(GlobalDecl gd,
llvm::SmallVectorImpl<CanQualType> &argTys) = 0;

AddedStructorArgCounts
addImplicitConstructorArgs(CIRGenFunction &cgf, const CXXConstructorDecl *d,
CXXCtorType type, bool forVirtualBase,
bool delegating, CallArgList &args);

clang::ImplicitParamDecl *getThisDecl(CIRGenFunction &cgf) {
return cgf.cxxabiThisDecl;
}

virtual AddedStructorArgs
getImplicitConstructorArgs(CIRGenFunction &cgf, const CXXConstructorDecl *d,
CXXCtorType type, bool forVirtualBase,
bool delegating) = 0;

/// Emit the ABI-specific prolog for the function
virtual void emitInstanceFunctionProlog(SourceLocation loc,
CIRGenFunction &cgf) = 0;
Expand Down Expand Up @@ -144,6 +200,17 @@ class CIRGenCXXABI {
CIRGenFunction &cgf, const CXXRecordDecl *vtableClass, BaseSubobject base,
const CXXRecordDecl *nearestVBase) = 0;

/// Insert any ABI-specific implicit parameters into the parameter list for a
/// function. This generally involves extra data for constructors and
/// destructors.
///
/// ABIs may also choose to override the return type, which has been
/// initialized with the type of 'this' if HasThisReturn(CGF.CurGD) is true or
/// the formal return type of the function otherwise.
virtual void addImplicitStructorParams(CIRGenFunction &cgf,
clang::QualType &resTy,
FunctionArgList &params) = 0;

/// Checks if ABI requires to initialize vptrs for given dynamic class.
virtual bool
doStructorsInitializeVPtrs(const clang::CXXRecordDecl *vtableClass) = 0;
Expand All @@ -162,6 +229,18 @@ class CIRGenCXXABI {

/// Gets the mangle context.
clang::MangleContext &getMangleContext() { return *mangleContext; }

clang::ImplicitParamDecl *&getStructorImplicitParamDecl(CIRGenFunction &cgf) {
return cgf.cxxStructorImplicitParamDecl;
}

mlir::Value getStructorImplicitParamValue(CIRGenFunction &cgf) {
return cgf.cxxStructorImplicitParamValue;
}

void setStructorImplicitParamValue(CIRGenFunction &cgf, mlir::Value val) {
cgf.cxxStructorImplicitParamValue = val;
}
};

/// Creates and Itanium-family ABI
Expand Down
20 changes: 12 additions & 8 deletions clang/lib/CIR/CodeGen/CIRGenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,10 @@ CIRGenTypes::arrangeCXXStructorDeclaration(GlobalDecl gd) {
if (passParams)
appendParameterTypes(*this, argTypes, fpt);

assert(!cir::MissingFeatures::implicitConstructorArgs());
// The structor signature may include implicit parameters.
[[maybe_unused]] CIRGenCXXABI::AddedStructorArgCounts addedArgs =
theCXXABI.buildStructorSignature(gd, argTypes);
assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());

RequiredArgs required =
(passParams && md->isVariadic() ? RequiredArgs(argTypes.size())
Expand Down Expand Up @@ -324,26 +327,27 @@ arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm,

/// Arrange a call to a C++ method, passing the given arguments.
///
/// extraPrefixArgs is the number of ABI-specific args passed after the `this`
/// parameter.
/// passProtoArgs indicates whether `args` has args for the parameters in the
/// given CXXConstructorDecl.
const CIRGenFunctionInfo &CIRGenTypes::arrangeCXXConstructorCall(
const CallArgList &args, const CXXConstructorDecl *d, CXXCtorType ctorKind,
bool passProtoArgs) {
unsigned extraPrefixArgs, unsigned extraSuffixArgs, bool passProtoArgs) {

// FIXME: Kill copy.
llvm::SmallVector<CanQualType, 16> argTypes;
for (const auto &arg : args)
argTypes.push_back(astContext.getCanonicalParamType(arg.ty));

assert(!cir::MissingFeatures::implicitConstructorArgs());
// +1 for implicit this, which should always be args[0]
unsigned totalPrefixArgs = 1;
unsigned totalPrefixArgs = 1 + extraPrefixArgs;

CanQual<FunctionProtoType> fpt = getFormalType(d);
RequiredArgs required =
passProtoArgs
? RequiredArgs::getFromProtoWithExtraSlots(fpt, totalPrefixArgs)
: RequiredArgs::All;
RequiredArgs required = passProtoArgs
? RequiredArgs::getFromProtoWithExtraSlots(
fpt, totalPrefixArgs + extraSuffixArgs)
: RequiredArgs::All;

GlobalDecl gd(d, ctorKind);
if (theCXXABI.hasThisReturn(gd))
Expand Down
Loading