Skip to content

Commit 018c5ba

Browse files
authored
[CIR] Implement MemberExpr with VarDecl for ComplexType (#154307)
This change adds support for MemberExpr with VarDecl ComplexType Issue: #141365
1 parent 2dc0a5f commit 018c5ba

File tree

3 files changed

+41
-17
lines changed

3 files changed

+41
-17
lines changed

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,10 +1046,22 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *e) {
10461046
llvm_unreachable("Invalid cast kind");
10471047
}
10481048

1049+
static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CIRGenFunction &cgf,
1050+
const MemberExpr *me) {
1051+
if (auto *vd = dyn_cast<VarDecl>(me->getMemberDecl())) {
1052+
// Try to emit static variable member expressions as DREs.
1053+
return DeclRefExpr::Create(
1054+
cgf.getContext(), NestedNameSpecifierLoc(), SourceLocation(), vd,
1055+
/*RefersToEnclosingVariableOrCapture=*/false, me->getExprLoc(),
1056+
me->getType(), me->getValueKind(), nullptr, nullptr, me->isNonOdrUse());
1057+
}
1058+
return nullptr;
1059+
}
1060+
10491061
LValue CIRGenFunction::emitMemberExpr(const MemberExpr *e) {
1050-
if (isa<VarDecl>(e->getMemberDecl())) {
1051-
cgm.errorNYI(e->getSourceRange(), "emitMemberExpr: VarDecl");
1052-
return LValue();
1062+
if (DeclRefExpr *dre = tryToConvertMemberExprToDeclRefExpr(*this, e)) {
1063+
emitIgnoredExpr(e->getBase());
1064+
return emitDeclRefLValue(dre);
10531065
}
10541066

10551067
Expr *baseExpr = e->getBase();
@@ -2102,18 +2114,6 @@ CIRGenFunction::tryEmitAsConstant(const DeclRefExpr *refExpr) {
21022114
return ConstantEmission::forValue(cstToEmit);
21032115
}
21042116

2105-
static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CIRGenFunction &cgf,
2106-
const MemberExpr *me) {
2107-
if (auto *vd = dyn_cast<VarDecl>(me->getMemberDecl())) {
2108-
// Try to emit static variable member expressions as DREs.
2109-
return DeclRefExpr::Create(
2110-
cgf.getContext(), NestedNameSpecifierLoc(), SourceLocation(), vd,
2111-
/*RefersToEnclosingVariableOrCapture=*/false, me->getExprLoc(),
2112-
me->getType(), me->getValueKind(), nullptr, nullptr, me->isNonOdrUse());
2113-
}
2114-
return nullptr;
2115-
}
2116-
21172117
CIRGenFunction::ConstantEmission
21182118
CIRGenFunction::tryEmitAsConstant(const MemberExpr *me) {
21192119
if (DeclRefExpr *dre = tryToConvertMemberExprToDeclRefExpr(*this, me))

clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
6464

6565
mlir::Value VisitMemberExpr(MemberExpr *me) {
6666
if (CIRGenFunction::ConstantEmission constant = cgf.tryEmitAsConstant(me)) {
67-
cgf.cgm.errorNYI("VisitMemberExpr tryEmitAsConstant");
68-
return {};
67+
cgf.emitIgnoredExpr(me->getBase());
68+
return emitConstant(constant, me);
6969
}
7070
return emitLoadOfLValue(me);
7171
}

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,3 +829,27 @@ void foo31() {
829829
// OGCG: %[[REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[ELEM_PTR]], i32 0, i32 0
830830
// OGCG: %[[REAL:.*]] = load i32, ptr %[[REAL_PTR]], align 4
831831
// OGCG: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4
832+
833+
struct Container {
834+
static int _Complex c;
835+
};
836+
837+
void foo32() {
838+
Container con;
839+
int r = __real__ con.c;
840+
}
841+
842+
// CIR: %[[REAL_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["r", init]
843+
// CIR: %[[ELEM_PTR:.*]] = cir.get_global @_ZN9Container1cE : !cir.ptr<!cir.complex<!s32i>>
844+
// CIR: %[[ELEM:.*]] = cir.load{{.*}} %[[ELEM_PTR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
845+
// CIR: %[[REAL:.*]] = cir.complex.real %[[ELEM]] : !cir.complex<!s32i> -> !s32i
846+
// CIR: cir.store{{.*}} %[[REAL]], %[[REAL_ADDR]] : !s32i, !cir.ptr<!s32i>
847+
848+
// LLVM: %[[REAL_ADDR:.*]] = alloca i32, i64 1, align 4
849+
// LLVM: %[[ELEM:.*]] = load { i32, i32 }, ptr @_ZN9Container1cE, align 4
850+
// LLVM: %[[REAL:.*]] = extractvalue { i32, i32 } %[[ELEM]], 0
851+
// LLVM: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4
852+
853+
// OGCG: %[[REAL_ADDR:.*]] = alloca i32, align 4
854+
// OGCG: %[[REAL:.*]] = load i32, ptr @_ZN9Container1cE, align 4
855+
// OGCG: store i32 %[[REAL]], ptr %[[REAL_ADDR]], align 4

0 commit comments

Comments
 (0)