Skip to content

Commit e2b2a2c

Browse files
committed
[CIR] Add test for begin/end range for statements
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 339dc95 commit e2b2a2c

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
@@ -304,7 +304,7 @@ void CIRGenFunction::emitCallArg(CallArgList &args, const clang::Expr *e,
304304

305305
if (e->isGLValue()) {
306306
assert(e->getObjectKind() == OK_Ordinary);
307-
args.add(emitReferenceBindingToExpr(e), argType);
307+
return args.add(emitReferenceBindingToExpr(e), argType);
308308
}
309309

310310
bool hasAggregateEvalKind = hasAggregateEvaluationKind(argType);
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)