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
1 change: 0 additions & 1 deletion clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ struct MissingFeatures {
static bool setFunctionAttributes() { return false; }

// CallOp handling
static bool opCallPseudoDtor() { return false; }
static bool opCallAggregateArgs() { return false; }
static bool opCallPaddingArgs() { return false; }
static bool opCallABIExtendArg() { return false; }
Expand Down
21 changes: 21 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class CIRGenCallee {
enum class SpecialKind : uintptr_t {
Invalid,
Builtin,
PseudoDestructor,

Last = Builtin,
};
Expand All @@ -54,12 +55,16 @@ class CIRGenCallee {
const clang::FunctionDecl *decl;
unsigned id;
};
struct PseudoDestructorInfoStorage {
const clang::CXXPseudoDestructorExpr *expr;
};

SpecialKind kindOrFunctionPtr;

union {
CIRGenCalleeInfo abstractInfo;
BuiltinInfoStorage builtinInfo;
PseudoDestructorInfoStorage pseudoDestructorInfo;
};

explicit CIRGenCallee(SpecialKind kind) : kindOrFunctionPtr(kind) {}
Expand Down Expand Up @@ -98,6 +103,22 @@ class CIRGenCallee {
return result;
}

static CIRGenCallee
forPseudoDestructor(const clang::CXXPseudoDestructorExpr *expr) {
CIRGenCallee result(SpecialKind::PseudoDestructor);
result.pseudoDestructorInfo.expr = expr;
return result;
}

bool isPseudoDestructor() const {
return kindOrFunctionPtr == SpecialKind::PseudoDestructor;
}

const CXXPseudoDestructorExpr *getPseudoDestructorExpr() const {
assert(isPseudoDestructor());
return pseudoDestructorInfo.expr;
}

bool isOrdinary() const {
return uintptr_t(kindOrFunctionPtr) > uintptr_t(SpecialKind::Last);
}
Expand Down
10 changes: 4 additions & 6 deletions clang/lib/CIR/CodeGen/CIRGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1543,10 +1543,10 @@ CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) {
cgm.errorNYI(e->getSourceRange(),
"emitCallee: call to member function is NYI");
return {};
} else if (auto *pde = dyn_cast<CXXPseudoDestructorExpr>(e)) {
return CIRGenCallee::forPseudoDestructor(pde);
}

assert(!cir::MissingFeatures::opCallPseudoDtor());

// Otherwise, we have an indirect reference.
mlir::Value calleePtr;
QualType functionType;
Expand Down Expand Up @@ -1598,10 +1598,8 @@ RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e,
return emitBuiltinExpr(callee.getBuiltinDecl(), callee.getBuiltinID(), e,
returnValue);

if (isa<CXXPseudoDestructorExpr>(e->getCallee())) {
cgm.errorNYI(e->getSourceRange(), "call to pseudo destructor");
}
assert(!cir::MissingFeatures::opCallPseudoDtor());
if (callee.isPseudoDestructor())
return emitCXXPseudoDestructorExpr(callee.getPseudoDestructorExpr());

return emitCall(e->getCallee()->getType(), callee, e, returnValue);
}
Expand Down
36 changes: 36 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//===--- CIRGenExprCXX.cpp - Emit CIR Code for C++ expressions ------------===//
//
// 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 contains code dealing with code generation of C++ expressions
//
//===----------------------------------------------------------------------===//

#include "CIRGenFunction.h"
#include "clang/AST/ExprCXX.h"

using namespace clang;
using namespace clang::CIRGen;

RValue CIRGenFunction::emitCXXPseudoDestructorExpr(
const CXXPseudoDestructorExpr *expr) {
QualType destroyedType = expr->getDestroyedType();
if (destroyedType.hasStrongOrWeakObjCLifetime()) {
assert(!cir::MissingFeatures::objCLifetime());
cgm.errorNYI(expr->getExprLoc(),
"emitCXXPseudoDestructorExpr: Objective-C lifetime is NYI");
} else {
// C++ [expr.pseudo]p1:
// The result shall only be used as the operand for the function call
// operator (), and the result of such a call has type void. The only
// effect is the evaluation of the postfix-expression before the dot or
// arrow.
emitIgnoredExpr(expr->getBase());
}

return RValue::get(nullptr);
}
2 changes: 2 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,8 @@ class CIRGenFunction : public CIRGenTypeCache {
const CXXMethodDecl *md,
ReturnValueSlot returnValue);

RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr);

void emitCtorPrologue(const clang::CXXConstructorDecl *ctor,
clang::CXXCtorType ctorType, FunctionArgList &args);

Expand Down
1 change: 1 addition & 0 deletions clang/lib/CIR/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ add_clang_library(clangCIR
CIRGenExprAggregate.cpp
CIRGenExprComplex.cpp
CIRGenExprConstant.cpp
CIRGenExprCXX.cpp
CIRGenExprScalar.cpp
CIRGenFunction.cpp
CIRGenItaniumCXXABI.cpp
Expand Down
16 changes: 15 additions & 1 deletion clang/test/CIR/CodeGen/call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,18 @@ void f14() {
// LLVM: call void @_Z3f13v() #[[LLVM_ATTR_0:.+]]
// LLVM: }

// LLLVM: attributes #[[LLVM_ATTR_0]] = { nounwind }
int f15();
void f16() {
using T = int;
f15().~T();
}

// CIR-LABEL: @_Z3f16v
// CIR-NEXT: %{{.+}} = cir.call @_Z3f15v() : () -> !s32i
// CIR: }

// LLVM-LABEL: define{{.+}} void @_Z3f16v() {
// LLVM-NEXT: %{{.+}} = call i32 @_Z3f15v()
// LLVM: }

// LLVM: attributes #[[LLVM_ATTR_0]] = { nounwind }