Hahnfeld created this revision.
Hahnfeld added reviewers: ABataev, hfinkel, carlo.bertolli, sfantao.
Hahnfeld added a subscriber: cfe-commits.
Pointer dereference is equal to access of first array element which is already
allowed for the `reduction` clause.
While at it also add test for CodeGen of reduction on array element which
seemed to be missing.
http://reviews.llvm.org/D18276
Files:
lib/CodeGen/CGStmtOpenMP.cpp
lib/Sema/SemaOpenMP.cpp
test/OpenMP/for_reduction_codegen.cpp
test/OpenMP/for_reduction_messages.cpp
test/OpenMP/parallel_ast_print.cpp
test/OpenMP/target_parallel_ast_print.cpp
test/OpenMP/target_parallel_for_ast_print.cpp
Index: test/OpenMP/target_parallel_for_ast_print.cpp
===================================================================
--- test/OpenMP/target_parallel_for_ast_print.cpp
+++ test/OpenMP/target_parallel_for_ast_print.cpp
@@ -104,8 +104,8 @@
// CHECK-NEXT: #pragma omp target parallel for default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(N) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:N][0:10])
// CHECK-NEXT: for (int i = 0; i < 2; ++i) {
// CHECK-NEXT: }
-#pragma omp target parallel for if (N) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:N][:argc]) reduction(&& : h)
-// CHECK-NEXT: #pragma omp target parallel for if(N) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:N][:argc]) reduction(&&: h)
+#pragma omp target parallel for if (N) num_threads(s) proc_bind(close) reduction(+:*arr1) reduction(^:e, f, arr[0:N][:argc]) reduction(&& : h)
+// CHECK-NEXT: #pragma omp target parallel for if(N) num_threads(s) proc_bind(close) reduction(+: *arr1) reduction(^: e,f,arr[0:N][:argc]) reduction(&&: h)
for (int i = 0; i < 2; ++i) {}
// CHECK-NEXT: for (int i = 0; i < 2; ++i) {
// CHECK-NEXT: }
@@ -191,8 +191,8 @@
// CHECK-NEXT: #pragma omp target parallel for default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
// CHECK-NEXT: for (int i = 0; i < 2; ++i) {
// CHECK-NEXT: }
-#pragma omp target parallel for if (5) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:5][:argc]) reduction(&& : h)
-// CHECK-NEXT: #pragma omp target parallel for if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: h)
+#pragma omp target parallel for if (5) num_threads(s) proc_bind(close) reduction(+:*arr1) reduction(^:e, f, arr[0:5][:argc]) reduction(&& : h)
+// CHECK-NEXT: #pragma omp target parallel for if(5) num_threads(s) proc_bind(close) reduction(+: *arr1) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: h)
for (int i = 0; i < 2; ++i) {}
// CHECK-NEXT: for (int i = 0; i < 2; ++i) {
// CHECK-NEXT: }
Index: test/OpenMP/target_parallel_ast_print.cpp
===================================================================
--- test/OpenMP/target_parallel_ast_print.cpp
+++ test/OpenMP/target_parallel_ast_print.cpp
@@ -39,7 +39,7 @@
h=2;
#pragma omp target parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10])
foo();
-#pragma omp target parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g)
+#pragma omp target parallel if (C) num_threads(s) proc_bind(close) reduction(+:*arr1) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g)
foo();
#pragma omp target parallel if (target:argc > 0)
foo();
@@ -74,7 +74,7 @@
// CHECK-NEXT: h = 2;
// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp target parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g)
+// CHECK-NEXT: #pragma omp target parallel if(5) num_threads(s) proc_bind(close) reduction(+: *arr1) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g)
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0)
// CHECK-NEXT: foo()
@@ -106,7 +106,7 @@
// CHECK-NEXT: h = 2;
// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10])
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp target parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g)
+// CHECK-NEXT: #pragma omp target parallel if(1) num_threads(s) proc_bind(close) reduction(+: *arr1) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g)
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0)
// CHECK-NEXT: foo()
@@ -138,7 +138,7 @@
// CHECK-NEXT: h = 2;
// CHECK-NEXT: #pragma omp target parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10])
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp target parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g)
+// CHECK-NEXT: #pragma omp target parallel if(C) num_threads(s) proc_bind(close) reduction(+: *arr1) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g)
// CHECK-NEXT: foo()
// CHECK-NEXT: #pragma omp target parallel if(target: argc > 0)
// CHECK-NEXT: foo()
Index: test/OpenMP/parallel_ast_print.cpp
===================================================================
--- test/OpenMP/parallel_ast_print.cpp
+++ test/OpenMP/parallel_ast_print.cpp
@@ -54,6 +54,9 @@
#pragma omp parallel reduction(&& : this->a) reduction(^: b[s.a.a])
for (int k = 0; k < s.a.a; ++k)
++s.a.a;
+#pragma omp parallel reduction(^: *b)
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
return *this;
}
};
@@ -70,6 +73,7 @@
// CHECK: #pragma omp parallel firstprivate(this->a) firstprivate(this->a)
// CHECK: #pragma omp parallel shared(this->a) shared(this->a)
// CHECK: #pragma omp parallel reduction(&&: this->a) reduction(^: this->b[s.a.a])
+// CHECK: #pragma omp parallel reduction(^: *this->b)
class S8 : public S7<S1> {
S8() {}
@@ -145,7 +149,7 @@
a=2;
#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10])
foo();
-#pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g)
+#pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(+: *arr1) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g)
foo();
return 0;
}
@@ -159,7 +163,7 @@
// CHECK-NEXT: a = 2;
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) copyin(S<int>::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10])
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g)
+// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close) reduction(+: *arr1) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g)
// CHECK-NEXT: foo()
// CHECK: template <typename T = long, int C = 1> long tmain(long argc, long *argv) {
// CHECK-NEXT: long b = argc, c, d, e, f, g;
@@ -170,7 +174,7 @@
// CHECK-NEXT: a = 2;
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) copyin(S<long>::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10])
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g)
+// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close) reduction(+: *arr1) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g)
// CHECK-NEXT: foo()
// CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
// CHECK-NEXT: T b = argc, c, d, e, f, g;
@@ -181,7 +185,7 @@
// CHECK-NEXT: a = 2;
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) copyin(S<T>::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10])
// CHECK-NEXT: foo()
-// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g)
+// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) reduction(+: *arr1) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g)
// CHECK-NEXT: foo()
enum Enum { };
@@ -202,9 +206,9 @@
// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d,arr1[argc]) reduction(*: e,arr[:10][0:argc])
foo();
// CHECK-NEXT: foo();
-// CHECK-NEXT: #pragma omp parallel if(b) num_threads(c) proc_bind(close) reduction(^: e,f) reduction(&&: g,arr[0:argc][:10])
+// CHECK-NEXT: #pragma omp parallel if(b) num_threads(c) proc_bind(close) reduction(+: *arr1) reduction(^: e,f) reduction(&&: g,arr[0:argc][:10])
// CHECK-NEXT: foo()
-#pragma omp parallel if (b) num_threads(c) proc_bind(close) reduction(^:e, f) reduction(&& : g, arr[0:argc][:10])
+#pragma omp parallel if (b) num_threads(c) proc_bind(close) reduction(+:*arr1) reduction(^:e, f) reduction(&& : g, arr[0:argc][:10])
foo();
return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
}
Index: test/OpenMP/for_reduction_messages.cpp
===================================================================
--- test/OpenMP/for_reduction_messages.cpp
+++ test/OpenMP/for_reduction_messages.cpp
@@ -147,6 +147,14 @@
for (int i = 0; i < 10; ++i)
foo();
#pragma omp parallel
+#pragma omp for reduction(max : *qa)
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel
+#pragma omp for reduction(max: !qa) // expected-error 2 {{expected variable name, array element or array section}}
+ for (int i = 0; i < 10; ++i)
+ foo();
+#pragma omp parallel
#pragma omp for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
for (int i = 0; i < 10; ++i)
foo();
@@ -207,6 +215,10 @@
#pragma omp for reduction(+ : qa[1], get()[0]) // expected-error 2 {{reduction variable must be shared}} expected-error {{expected variable name as a base of the array subscript}}
for (int i = 0; i < 10; ++i)
foo();
+#pragma omp parallel private(qa) // expected-note 2 {{defined as private}}
+#pragma omp for reduction(+ : *qa, *(get())) // expected-error 2 {{reduction variable must be shared}} expected-error {{expected variable name as a base of the array subscript}}
+ for (int i = 0; i < 10; ++i)
+ foo();
#pragma omp parallel shared(qa)
#pragma omp for reduction(+ : qa[1], qa[0]) // expected-error 2 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 2 {{previously referenced here}}
for (int i = 0; i < 10; ++i)
Index: test/OpenMP/for_reduction_codegen.cpp
===================================================================
--- test/OpenMP/for_reduction_codegen.cpp
+++ test/OpenMP/for_reduction_codegen.cpp
@@ -217,6 +217,14 @@
#pragma omp for reduction(& : var3)
for (int i = 0; i < 10; ++i)
;
+#pragma omp parallel
+#pragma omp for reduction(& : var3[1])
+ for (int i = 0; i < 10; ++i)
+ ;
+#pragma omp parallel
+#pragma omp for reduction(& : *var3)
+ for (int i = 0; i < 10; ++i)
+ ;
return tmain<int>();
#endif
}
@@ -231,6 +239,8 @@
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK4:@.+]] to void
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK5:@.+]] to void
// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK6:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK7:@.+]] to void
+// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK8:@.+]] to void
// CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]()
// CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]*
// CHECK: ret
@@ -1002,6 +1012,42 @@
// CHECK: ret void
+// CHECK: define internal void [[MAIN_MICROTASK7]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}})
+
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[VAR3_ELEM:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 1
+
+// CHECK: [[VAR3_PRIV_ELEM:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[VAR3_PRIV]],
+// CHECK: [[VAR3_PRIV_ELEM_CASTED:%.+]] = bitcast [[S_FLOAT_TY]]* [[VAR3_PRIV_ELEM]] to [2 x [[S_FLOAT_TY]]]*
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV_ELEM_CASTED]], [2 x [[S_FLOAT_TY]]]** %
+
+// CHECK: ret void
+
+// CHECK: define internal void [[MAIN_MICROTASK8]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [2 x [[S_FLOAT_TY]]]* dereferenceable(8) %{{.+}})
+
+// CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [2 x [[S_FLOAT_TY]]]*,
+// CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]],
+
+// Reduction list for runtime.
+// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*],
+
+// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+
+// CHECK: load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+
+// CHECK: [[VAR3_PRIV_ELEM:%.+]] = getelementptr [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]],
+// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV_ELEM_CASTED]], [2 x [[S_FLOAT_TY]]]** %
+
+// CHECK: ret void
+
// CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]()
// CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]],
// CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]])
Index: lib/Sema/SemaOpenMP.cpp
===================================================================
--- lib/Sema/SemaOpenMP.cpp
+++ lib/Sema/SemaOpenMP.cpp
@@ -7138,6 +7138,11 @@
Base = TempASE->getBase()->IgnoreParenImpCasts();
RefExpr = Base;
IsArrayExpr = OMPArraySection;
+ } else if (auto *UO = dyn_cast_or_null<UnaryOperator>(RefExpr)) {
+ if (UO->getOpcode() == UO_Deref) {
+ RefExpr = UO->getSubExpr()->IgnoreParenImpCasts();
+ IsArrayExpr = ArraySubscript;
+ }
}
}
ELoc = RefExpr->getExprLoc();
@@ -8077,6 +8082,7 @@
QualType Type;
auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
+ auto *UO = dyn_cast<UnaryOperator>(RefExpr->IgnoreParens());
if (ASE)
Type = ASE->getType().getNonReferenceType();
else if (OASE) {
@@ -8086,6 +8092,9 @@
else
Type = BaseType->getPointeeType();
Type = Type.getNonReferenceType();
+ } else if (UO) {
+ assert(UO->getOpcode() == UO_Deref && "should be a dereference");
+ Type = UO->getType().getNonReferenceType();
} else
Type = Context.getBaseElementType(D->getType().getNonReferenceType());
auto *VD = dyn_cast<VarDecl>(D);
Index: lib/CodeGen/CGStmtOpenMP.cpp
===================================================================
--- lib/CodeGen/CGStmtOpenMP.cpp
+++ lib/CodeGen/CGStmtOpenMP.cpp
@@ -910,13 +910,23 @@
PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address {
return GetAddrOfLocalVar(PrivateVD);
});
- } else if (auto *ASE = dyn_cast<ArraySubscriptExpr>(IRef)) {
- auto *Base = ASE->getBase()->IgnoreParenImpCasts();
- while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
- Base = TempASE->getBase()->IgnoreParenImpCasts();
+ } else if (isa<ArraySubscriptExpr>(IRef) || isa<UnaryOperator>(IRef)) {
+ const Expr *Array;
+ const Expr *Base;
+ if (auto* ASE = dyn_cast<ArraySubscriptExpr>(IRef)) {
+ Array = ASE;
+ Base = ASE->getBase()->IgnoreParenImpCasts();
+ while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
+ Base = TempASE->getBase()->IgnoreParenImpCasts();
+ } else {
+ auto* UO = cast<UnaryOperator>(IRef);
+ assert(UO->getOpcode() == UO_Deref && "should be a dereference");
+ Array = UO;
+ Base = UO->getSubExpr()->IgnoreParenImpCasts();
+ }
auto *DE = cast<DeclRefExpr>(Base);
auto *OrigVD = cast<VarDecl>(DE->getDecl());
- auto ASELValue = EmitLValue(ASE);
+ auto ASELValue = EmitLValue(Array);
auto OriginalBaseLValue = EmitLValue(DE);
LValue BaseLValue = loadToBegin(
*this, OrigVD->getType(), ASELValue.getType(), OriginalBaseLValue);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits