Skip to content

Commit c3ca0fb

Browse files
authored
[CIR] Add test for begin/end range for statements (#139134)
This adds a test to verify range for loops based on begin() and end() funtion calls. The functionality to enable this was added in previous commits, but those commits were only indirectly related to this test. The general intent of this commit is to work towards enabling iterator-based range for loops. The test did reveal one minor problem in call argument handling, which is corrected here.
1 parent 49b79d5 commit c3ca0fb

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

clang/lib/CIR/CodeGen/CIRGenCall.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,
192192

193193
if (e->isGLValue()) {
194194
assert(e->getObjectKind() == OK_Ordinary);
195-
args.add(emitReferenceBindingToExpr(e), argType);
195+
return args.add(emitReferenceBindingToExpr(e), argType);
196196
}
197197

198198
bool hasAggregateEvalKind = hasAggregateEvaluationKind(argType);

clang/test/CIR/CodeGen/forrange.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
3+
4+
struct Element {};
5+
struct Container {};
6+
7+
Element *begin(Container &);
8+
Element *end(Container &);
9+
10+
void for_range() {
11+
Container c;
12+
for (Element &e : c)
13+
;
14+
}
15+
16+
// CIR: cir.func @_Z5beginR9Container(!cir.ptr<!rec_Container>) -> !cir.ptr<!rec_Element>
17+
// CIR: cir.func @_Z3endR9Container(!cir.ptr<!rec_Container>) -> !cir.ptr<!rec_Element
18+
19+
// CIR: cir.func @_Z9for_rangev()
20+
// CIR: %[[C_ADDR:.*]] = cir.alloca !rec_Container{{.*}} ["c"]
21+
// CIR: cir.scope {
22+
// CIR: %[[RANGE_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Container>{{.*}} ["__range1", init, const]
23+
// CIR: %[[BEGIN_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Element>{{.*}} ["__begin1", init]
24+
// CIR: %[[END_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Element>{{.*}} ["__end1", init]
25+
// CIR: %[[E_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Element>{{.*}} ["e", init, const]
26+
// CIR: cir.store %[[C_ADDR]], %[[RANGE_ADDR]]
27+
// CIR: %[[C_REF:.*]] = cir.load %[[RANGE_ADDR]]
28+
// CIR: %[[BEGIN:.*]] = cir.call @_Z5beginR9Container(%[[C_REF]])
29+
// CIR: cir.store %[[BEGIN]], %[[BEGIN_ADDR]]
30+
// CIR: %[[C_REF2:.*]] = cir.load %[[RANGE_ADDR]]
31+
// CIR: %[[END:.*]] = cir.call @_Z3endR9Container(%[[C_REF2]])
32+
// CIR: cir.store %[[END]], %[[END_ADDR]]
33+
// CIR: cir.for : cond {
34+
// CIR: %[[BEGIN:.*]] = cir.load %[[BEGIN_ADDR]]
35+
// CIR: %[[END:.*]] = cir.load %[[END_ADDR]]
36+
// CIR: %[[CMP:.*]] = cir.cmp(ne, %[[BEGIN]], %[[END]])
37+
// CIR: cir.condition(%[[CMP]])
38+
// CIR: } body {
39+
// CIR: %[[E:.*]] = cir.load deref %[[BEGIN_ADDR]]
40+
// CIR: cir.store %[[E]], %[[E_ADDR]]
41+
// CIR: cir.yield
42+
// CIR: } step {
43+
// CIR: %[[BEGIN:.*]] = cir.load %[[BEGIN_ADDR]]
44+
// CIR: %[[STEP:.*]] = cir.const #cir.int<1>
45+
// CIR: %[[NEXT:.*]] = cir.ptr_stride(%[[BEGIN]] {{.*}}, %[[STEP]] {{.*}})
46+
// CIR: cir.store %[[NEXT]], %[[BEGIN_ADDR]]
47+
// CIR: cir.yield
48+
// CIR: }
49+
// CIR: }

0 commit comments

Comments
 (0)