Skip to content

Commit 2c3c8ef

Browse files
bcardosolopeslanza
authored andcommittedOct 19, 2024
[CIR][CIRGen][NFC] Add more skeleton for handling inheritance ctors
While here add some bits for ptr auth and match OG.

File tree

7 files changed

+130
-4
lines changed

7 files changed

+130
-4
lines changed
 

‎clang/include/clang/CIR/MissingFeatures.h

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ struct MissingFeatures {
6060
static bool tbaa() { return false; }
6161
static bool cleanups() { return false; }
6262
static bool emitNullabilityCheck() { return false; }
63+
static bool ptrAuth() { return false; }
6364

6465
// GNU vectors are done, but other kinds of vectors haven't been implemented.
6566
static bool scalableVectors() { return false; }

‎clang/lib/CIR/CodeGen/Address.h

+7
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ class Address {
9191
return PointerAndKnownNonNull.getPointer();
9292
}
9393

94+
mlir::Value getBasePointer() const {
95+
// TODO(cir): Remove the version above when we catchup with OG codegen on
96+
// ptr auth.
97+
assert(isValid() && "pointer isn't valid");
98+
return getPointer();
99+
}
100+
94101
/// Return the alignment of this pointer.
95102
clang::CharUnits getAlignment() const {
96103
// assert(isValid());

‎clang/lib/CIR/CodeGen/CIRGenClass.cpp

+61-1
Original file line numberDiff line numberDiff line change
@@ -1811,6 +1811,30 @@ void CIRGenFunction::buildCXXAggrConstructorCall(
18111811
constantCount.erase();
18121812
}
18131813

1814+
static bool canEmitDelegateCallArgs(CIRGenFunction &CGF,
1815+
const CXXConstructorDecl *Ctor,
1816+
CXXCtorType Type, CallArgList &Args) {
1817+
// We can't forward a variadic call.
1818+
if (Ctor->isVariadic())
1819+
return false;
1820+
1821+
if (CGF.getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
1822+
// If the parameters are callee-cleanup, it's not safe to forward.
1823+
for (auto *P : Ctor->parameters())
1824+
if (P->needsDestruction(CGF.getContext()))
1825+
return false;
1826+
1827+
// Likewise if they're inalloca.
1828+
const CIRGenFunctionInfo &Info =
1829+
CGF.CGM.getTypes().arrangeCXXConstructorCall(Args, Ctor, Type, 0, 0);
1830+
if (Info.usesInAlloca())
1831+
return false;
1832+
}
1833+
1834+
// Anything else should be OK.
1835+
return true;
1836+
}
1837+
18141838
void CIRGenFunction::buildCXXConstructorCall(const clang::CXXConstructorDecl *D,
18151839
clang::CXXCtorType Type,
18161840
bool ForVirtualBase,
@@ -1872,7 +1896,14 @@ void CIRGenFunction::buildCXXConstructorCall(
18721896

18731897
bool PassPrototypeArgs = true;
18741898

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

18771908
// Insert any ABI-specific implicit constructor arguments.
18781909
CIRGenCXXABI::AddedStructorArgCounts ExtraArgs =
@@ -1891,4 +1922,33 @@ void CIRGenFunction::buildCXXConstructorCall(
18911922
ClassDecl->isDynamicClass() || Type == Ctor_Base ||
18921923
!CGM.getCodeGenOpts().StrictVTablePointers &&
18931924
"vtable assumption loads NYI");
1925+
}
1926+
1927+
void CIRGenFunction::buildInheritedCXXConstructorCall(
1928+
const CXXConstructorDecl *D, bool ForVirtualBase, Address This,
1929+
bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E) {
1930+
CallArgList Args;
1931+
CallArg ThisArg(RValue::get(getAsNaturalPointerTo(
1932+
This, D->getThisType()->getPointeeType())),
1933+
D->getThisType());
1934+
1935+
// Forward the parameters.
1936+
if (InheritedFromVBase &&
1937+
CGM.getTarget().getCXXABI().hasConstructorVariants()) {
1938+
llvm_unreachable("NYI");
1939+
} else if (!CXXInheritedCtorInitExprArgs.empty()) {
1940+
// The inheriting constructor was inlined; just inject its arguments.
1941+
llvm_unreachable("NYI");
1942+
} else {
1943+
// The inheriting constructor was not inlined. Emit delegating arguments.
1944+
llvm_unreachable("NYI");
1945+
}
1946+
1947+
llvm_unreachable("NYI");
1948+
}
1949+
1950+
void CIRGenFunction::buildInlinedInheritingCXXConstructorCall(
1951+
const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase,
1952+
bool Delegating, CallArgList &Args) {
1953+
llvm_unreachable("NYI");
18941954
}

‎clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
296296
}
297297
void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
298298
void VisitCXXConstructExpr(const CXXConstructExpr *E);
299-
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E) {
300-
llvm_unreachable("NYI");
301-
}
299+
void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E);
302300
void VisitLambdaExpr(LambdaExpr *E);
303301
void VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
304302
ASTContext &Ctx = CGF.getContext();
@@ -1456,6 +1454,14 @@ void AggExprEmitter::VisitBinComma(const BinaryOperator *E) {
14561454
Visit(E->getRHS());
14571455
}
14581456

1457+
void AggExprEmitter::VisitCXXInheritedCtorInitExpr(
1458+
const CXXInheritedCtorInitExpr *E) {
1459+
AggValueSlot Slot = EnsureSlot(CGF.getLoc(E->getSourceRange()), E->getType());
1460+
CGF.buildInheritedCXXConstructorCall(E->getConstructor(),
1461+
E->constructsVBase(), Slot.getAddress(),
1462+
E->inheritedFromVBase(), E);
1463+
}
1464+
14591465
//===----------------------------------------------------------------------===//
14601466
// Helpers and dispatcher
14611467
//===----------------------------------------------------------------------===//

‎clang/lib/CIR/CodeGen/CIRGenFunction.h

+28
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,24 @@ class CIRGenFunction : public CIRGenTypeCache {
655655
void buildCXXConstructExpr(const clang::CXXConstructExpr *E,
656656
AggValueSlot Dest);
657657

658+
/// Emit a call to an inheriting constructor (that is, one that invokes a
659+
/// constructor inherited from a base class) by inlining its definition. This
660+
/// is necessary if the ABI does not support forwarding the arguments to the
661+
/// base class constructor (because they're variadic or similar).
662+
void buildInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor,
663+
CXXCtorType CtorType,
664+
bool ForVirtualBase,
665+
bool Delegating,
666+
CallArgList &Args);
667+
668+
/// Emit a call to a constructor inherited from a base class, passing the
669+
/// current constructor's arguments along unmodified (without even making
670+
/// a copy).
671+
void buildInheritedCXXConstructorCall(const CXXConstructorDecl *D,
672+
bool ForVirtualBase, Address This,
673+
bool InheritedFromVBase,
674+
const CXXInheritedCtorInitExpr *E);
675+
658676
void buildCXXConstructorCall(const clang::CXXConstructorDecl *D,
659677
clang::CXXCtorType Type, bool ForVirtualBase,
660678
bool Delegating, AggValueSlot ThisAVS,
@@ -920,6 +938,12 @@ class CIRGenFunction : public CIRGenTypeCache {
920938
RValue buildCallExpr(const clang::CallExpr *E,
921939
ReturnValueSlot ReturnValue = ReturnValueSlot());
922940

941+
Address getAsNaturalAddressOf(Address Addr, QualType PointeeTy);
942+
943+
mlir::Value getAsNaturalPointerTo(Address Addr, QualType PointeeType) {
944+
return getAsNaturalAddressOf(Addr, PointeeType).getBasePointer();
945+
}
946+
923947
mlir::Value buildRuntimeCall(mlir::Location loc, mlir::cir::FuncOp callee,
924948
ArrayRef<mlir::Value> args = {});
925949

@@ -1937,6 +1961,10 @@ class CIRGenFunction : public CIRGenTypeCache {
19371961
Destroyer *destroyer, bool checkZeroLength,
19381962
bool useEHCleanup);
19391963

1964+
/// The values of function arguments to use when evaluating
1965+
/// CXXInheritedCtorInitExprs within this context.
1966+
CallArgList CXXInheritedCtorInitExprArgs;
1967+
19401968
// Points to the outermost active conditional control. This is used so that
19411969
// we know if a temporary should be destroyed conditionally.
19421970
ConditionalEvaluation *OutermostConditional = nullptr;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===--- CIRGenPointerAuth.cpp - CIR generation for ptr auth --------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file contains common routines relating to the emission of
10+
// pointer authentication operations.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "CIRGenFunction.h"
15+
16+
using namespace clang;
17+
using namespace cir;
18+
19+
Address CIRGenFunction::getAsNaturalAddressOf(Address Addr,
20+
QualType PointeeTy) {
21+
assert(!MissingFeatures::ptrAuth() && "NYI");
22+
return Addr;
23+
}

‎clang/lib/CIR/CodeGen/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ add_clang_library(clangCIR
3434
CIRGenOpenCLRuntime.cpp
3535
CIRGenOpenCL.cpp
3636
CIRGenOpenMPRuntime.cpp
37+
CIRGenPointerAuth.cpp
3738
CIRGenStmt.cpp
3839
CIRGenStmtOpenMP.cpp
3940
CIRGenTBAA.cpp

0 commit comments

Comments
 (0)
Please sign in to comment.