Skip to content

Commit

Permalink
[CIR][CIRGen][NFC] Add more skeleton for handling inheritance ctors
Browse files Browse the repository at this point in the history
While here add some bits for ptr auth and match OG.
  • Loading branch information
bcardosolopes committed Oct 18, 2024
1 parent 199228d commit 73e3897
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 4 deletions.
1 change: 1 addition & 0 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct MissingFeatures {
static bool tbaa() { return false; }
static bool cleanups() { return false; }
static bool emitNullabilityCheck() { return false; }
static bool ptrAuth() { return false; }

// GNU vectors are done, but other kinds of vectors haven't been implemented.
static bool scalableVectors() { return false; }
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/CIR/CodeGen/Address.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ class Address {
return PointerAndKnownNonNull.getPointer();
}

mlir::Value getBasePointer() const {
// TODO(cir): Remove the version above when we catchup with OG codegen on
// ptr auth.
assert(isValid() && "pointer isn't valid");
return getPointer();
}

/// Return the alignment of this pointer.
clang::CharUnits getAlignment() const {
// assert(isValid());
Expand Down
62 changes: 61 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1811,6 +1811,30 @@ void CIRGenFunction::buildCXXAggrConstructorCall(
constantCount.erase();
}

static bool canEmitDelegateCallArgs(CIRGenFunction &CGF,
const CXXConstructorDecl *Ctor,
CXXCtorType Type, CallArgList &Args) {
// We can't forward a variadic call.
if (Ctor->isVariadic())
return false;

if (CGF.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
// If the parameters are callee-cleanup, it's not safe to forward.
for (auto *P : Ctor->parameters())
if (P->needsDestruction(CGF.getContext()))
return false;

// Likewise if they're inalloca.
const CIRGenFunctionInfo &Info =
CGF.CGM.getTypes().arrangeCXXConstructorCall(Args, Ctor, Type, 0, 0);
if (Info.usesInAlloca())
return false;
}

// Anything else should be OK.
return true;
}

void CIRGenFunction::buildCXXConstructorCall(const clang::CXXConstructorDecl *D,
clang::CXXCtorType Type,
bool ForVirtualBase,
Expand Down Expand Up @@ -1872,7 +1896,14 @@ void CIRGenFunction::buildCXXConstructorCall(

bool PassPrototypeArgs = true;

assert(!D->getInheritedConstructor() && "inheritance NYI");
// Check whether we can actually emit the constructor before trying to do so.
if (auto Inherited = D->getInheritedConstructor()) {
PassPrototypeArgs = getTypes().inheritingCtorHasParams(Inherited, Type);
if (PassPrototypeArgs && !canEmitDelegateCallArgs(*this, D, Type, Args)) {
llvm_unreachable("NYI");
return;
}
}

// Insert any ABI-specific implicit constructor arguments.
CIRGenCXXABI::AddedStructorArgCounts ExtraArgs =
Expand All @@ -1891,4 +1922,33 @@ void CIRGenFunction::buildCXXConstructorCall(
ClassDecl->isDynamicClass() || Type == Ctor_Base ||
!CGM.getCodeGenOpts().StrictVTablePointers &&
"vtable assumption loads NYI");
}

void CIRGenFunction::buildInheritedCXXConstructorCall(
const CXXConstructorDecl *D, bool ForVirtualBase, Address This,
bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) {
CallArgList Args;
CallArg ThisArg(RValue::get(getAsNaturalPointerTo(
This, D->getThisType()->getPointeeType())),
D->getThisType());

// Forward the parameters.
if (InheritedFromVBase &&
CGM.getTarget().getCXXABI().hasConstructorVariants()) {
llvm_unreachable("NYI");
} else if (!CXXInheritedCtorInitExprArgs.empty()) {
// The inheriting constructor was inlined; just inject its arguments.
llvm_unreachable("NYI");
} else {
// The inheriting constructor was not inlined. Emit delegating arguments.
llvm_unreachable("NYI");
}

llvm_unreachable("NYI");
}

void CIRGenFunction::buildInlinedInheritingCXXConstructorCall(
const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase,
bool Delegating, CallArgList &Args) {
llvm_unreachable("NYI");
}
12 changes: 9 additions & 3 deletions clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
}
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
void VisitCXXConstructExpr(const CXXConstructExpr *E);
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E) {
llvm_unreachable("NYI");
}
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E);
void VisitLambdaExpr(LambdaExpr *E);
void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
ASTContext &Ctx = CGF.getContext();
Expand Down Expand Up @@ -1456,6 +1454,14 @@ void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
Visit(E->getRHS());
}

void AggExprEmitter::VisitCXXInheritedCtorInitExpr(
const CXXInheritedCtorInitExpr *E) {
AggValueSlot Slot = EnsureSlot(CGF.getLoc(E->getSourceRange()), E->getType());
CGF.buildInheritedCXXConstructorCall(E->getConstructor(),
E->constructsVBase(), Slot.getAddress(),
E->inheritedFromVBase(), E);
}

//===----------------------------------------------------------------------===//
// Helpers and dispatcher
//===----------------------------------------------------------------------===//
Expand Down
28 changes: 28 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,24 @@ class CIRGenFunction : public CIRGenTypeCache {
void buildCXXConstructExpr(const clang::CXXConstructExpr *E,
AggValueSlot Dest);

/// Emit a call to an inheriting constructor (that is, one that invokes a
/// constructor inherited from a base class) by inlining its definition. This
/// is necessary if the ABI does not support forwarding the arguments to the
/// base class constructor (because they're variadic or similar).
void buildInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor,
CXXCtorType CtorType,
bool ForVirtualBase,
bool Delegating,
CallArgList &Args);

/// Emit a call to a constructor inherited from a base class, passing the
/// current constructor's arguments along unmodified (without even making
/// a copy).
void buildInheritedCXXConstructorCall(const CXXConstructorDecl *D,
bool ForVirtualBase, Address This,
bool InheritedFromVBase,
const CXXInheritedCtorInitExpr *E);

void buildCXXConstructorCall(const clang::CXXConstructorDecl *D,
clang::CXXCtorType Type, bool ForVirtualBase,
bool Delegating, AggValueSlot ThisAVS,
Expand Down Expand Up @@ -920,6 +938,12 @@ class CIRGenFunction : public CIRGenTypeCache {
RValue buildCallExpr(const clang::CallExpr *E,
ReturnValueSlot ReturnValue = ReturnValueSlot());

Address getAsNaturalAddressOf(Address Addr, QualType PointeeTy);

mlir::Value getAsNaturalPointerTo(Address Addr, QualType PointeeType) {
return getAsNaturalAddressOf(Addr, PointeeType).getBasePointer();
}

mlir::Value buildRuntimeCall(mlir::Location loc, mlir::cir::FuncOp callee,
ArrayRef<mlir::Value> args = {});

Expand Down Expand Up @@ -1937,6 +1961,10 @@ class CIRGenFunction : public CIRGenTypeCache {
Destroyer *destroyer, bool checkZeroLength,
bool useEHCleanup);

/// The values of function arguments to use when evaluating
/// CXXInheritedCtorInitExprs within this context.
CallArgList CXXInheritedCtorInitExprArgs;

// Points to the outermost active conditional control. This is used so that
// we know if a temporary should be destroyed conditionally.
ConditionalEvaluation *OutermostConditional = nullptr;
Expand Down
23 changes: 23 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenPointerAuth.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===--- CIRGenPointerAuth.cpp - CIR generation for ptr auth --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains common routines relating to the emission of
// pointer authentication operations.
//
//===----------------------------------------------------------------------===//

#include "CIRGenFunction.h"

using namespace clang;
using namespace cir;

Address CIRGenFunction::getAsNaturalAddressOf(Address Addr,
QualType PointeeTy) {
assert(!MissingFeatures::ptrAuth() && "NYI");
return Addr;
}
1 change: 1 addition & 0 deletions clang/lib/CIR/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ add_clang_library(clangCIR
CIRGenOpenCLRuntime.cpp
CIRGenOpenCL.cpp
CIRGenOpenMPRuntime.cpp
CIRGenPointerAuth.cpp
CIRGenStmt.cpp
CIRGenStmtOpenMP.cpp
CIRGenTBAA.cpp
Expand Down

0 comments on commit 73e3897

Please sign in to comment.