Removed 'if (auto *FD = CapturedStmtInfo->lookup(VD))' from codegen for
variable captured in CapturedStmt
http://reviews.llvm.org/D6259
Files:
include/clang/AST/Expr.h
include/clang/AST/Stmt.h
include/clang/Sema/Sema.h
lib/AST/ASTImporter.cpp
lib/AST/Expr.cpp
lib/Analysis/BodyFarm.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGStmtOpenMP.cpp
lib/CodeGen/CodeGenFunction.h
lib/Frontend/Rewrite/RewriteModernObjC.cpp
lib/Frontend/Rewrite/RewriteObjC.cpp
lib/Sema/SemaChecking.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaOpenMP.cpp
lib/Sema/SemaStmt.cpp
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriterDecl.cpp
lib/Serialization/ASTWriterStmt.cpp
test/OpenMP/parallel_firstprivate_codegen.cpp
test/OpenMP/parallel_private_codegen.cpp
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: test/OpenMP/parallel_firstprivate_codegen.cpp
===================================================================
--- test/OpenMP/parallel_firstprivate_codegen.cpp
+++ test/OpenMP/parallel_firstprivate_codegen.cpp
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
@@ -12,7 +14,7 @@
~St() {}
};
-volatile int g;
+volatile int g = 1212;
template <class T>
struct S {
@@ -47,6 +49,83 @@
}
int main() {
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]]
+ // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8*
+ // LAMBDA: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
+#pragma omp parallel firstprivate(g)
+ {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
+ // LAMBDA: [[ARG:%.+]] = load %{{.+}}** [[ARG_REF]]
+ // LAMBDA: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_REF_ADDR]]
+ // LAMBDA: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}* [[G_REF]]
+ // LAMBDA: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
+ // LAMBDA: call void @__kmpc_barrier(
+ g = 1;
+ // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ }();
+ }
+ }();
+ return 0;
+#elif defined(BLOCKS)
+ // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // BLOCKS-LABEL: @main
+ // BLOCKS: call void {{%.+}}(i8*
+ ^{
+ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
+ // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]]
+ // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8*
+ // BLOCKS: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
+#pragma omp parallel firstprivate(g)
+ {
+ // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
+ // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
+ // BLOCKS: [[ARG:%.+]] = load %{{.+}}** [[ARG_REF]]
+ // BLOCKS: [[G_REF_ADDR:%.+]] = getelementptr inbounds %{{.+}}* [[ARG]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // BLOCKS: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_REF_ADDR]]
+ // BLOCKS: [[G_VAL:%.+]] = load volatile i{{[0-9]+}}* [[G_REF]]
+ // BLOCKS: store volatile i{{[0-9]+}} [[G_VAL]], i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
+ // BLOCKS: call void @__kmpc_barrier(
+ g = 1;
+ // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: call void {{%.+}}(i8*
+ ^{
+ // BLOCKS: define {{.+}} void {{@.+}}(i8*
+ g = 2;
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: ret
+ }();
+ }
+ }();
+ return 0;
+#else
S<float> test;
int t_var = 0;
int vec[] = {1, 2};
@@ -58,6 +137,7 @@
s_arr[0] = var;
}
return tmain<int>();
+#endif
}
// CHECK: define {{.*}}i{{[0-9]+}} @main()
Index: test/OpenMP/parallel_private_codegen.cpp
===================================================================
--- test/OpenMP/parallel_private_codegen.cpp
+++ test/OpenMP/parallel_private_codegen.cpp
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp=libiomp5 -x c++ -triple x86_64-unknown-unknown -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -std=c++11 -DLAMBDA -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=LAMBDA %s
+// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -x c++ -fblocks -DBLOCKS -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck -check-prefix=BLOCKS %s
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
@@ -14,15 +16,17 @@
~S() {}
};
+volatile int g = 1212;
+
// CHECK: [[S_FLOAT_TY:%.+]] = type { float }
// CHECK: [[CAP_MAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_FLOAT_TY]]]*, [[S_FLOAT_TY]]* }
// CHECK: [[S_INT_TY:%.+]] = type { i{{[0-9]+}} }
// CHECK: [[CAP_TMAIN_TY:%.+]] = type { [2 x i{{[0-9]+}}]*, i{{[0-9]+}}*, [2 x [[S_INT_TY]]]*, [[S_INT_TY]]* }
// CHECK: [[IMPLICIT_BARRIER_LOC:@.+]] = private unnamed_addr constant %{{.+}} { i32 0, i32 66, i32 0, i32 0, i8*
template <typename T>
T tmain() {
S<T> test;
- T t_var;
+ T t_var = T();
T vec[] = {1, 2};
S<T> s_arr[] = {1, 2};
S<T> var(3);
@@ -35,8 +39,75 @@
}
int main() {
+#ifdef LAMBDA
+ // LAMBDA: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // LAMBDA-LABEL: @main
+ // LAMBDA: call void [[OUTER_LAMBDA:@.+]](
+ [&]() {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
+ // LAMBDA: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]]
+ // LAMBDA: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8*
+ // LAMBDA: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
+#pragma omp parallel private(g)
+ {
+ // LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
+ // LAMBDA: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // LAMBDA: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
+ // LAMBDA: call void @__kmpc_barrier(
+ g = 1;
+ // LAMBDA: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
+ // LAMBDA: [[G_PRIVATE_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}* [[ARG:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: store i{{[0-9]+}}* [[G_PRIVATE_ADDR]], i{{[0-9]+}}** [[G_PRIVATE_ADDR_REF]]
+ // LAMBDA: call void [[INNER_LAMBDA:@.+]](%{{.+}}* [[ARG]])
+ [&]() {
+ // LAMBDA: define {{.+}} void [[INNER_LAMBDA]](%{{.+}}* [[ARG_PTR:%.+]])
+ // LAMBDA: store %{{.+}}* [[ARG_PTR]], %{{.+}}** [[ARG_PTR_REF:%.+]],
+ g = 2;
+ // LAMBDA: [[ARG_PTR:%.+]] = load %{{.+}}** [[ARG_PTR_REF]]
+ // LAMBDA: [[G_PTR_REF:%.+]] = getelementptr inbounds %{{.+}}* [[ARG_PTR]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // LAMBDA: [[G_REF:%.+]] = load i{{[0-9]+}}** [[G_PTR_REF]]
+ // LAMBDA: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}* [[G_REF]]
+ }();
+ }
+ }();
+ return 0;
+#elif defined(BLOCKS)
+ // BLOCKS: [[G:@.+]] = global i{{[0-9]+}} 1212,
+ // BLOCKS-LABEL: @main
+ // BLOCKS: call void {{%.+}}(i8*
+ ^{
+ // BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
+ // BLOCKS: [[G_LOCAL_REF:%.+]] = getelementptr inbounds %{{.+}}* [[AGG_CAPTURED:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
+ // BLOCKS: store i{{[0-9]+}}* [[G]], i{{[0-9]+}}** [[G_LOCAL_REF]]
+ // BLOCKS: [[ARG:%.+]] = bitcast %{{.+}}* [[AGG_CAPTURED]] to i8*
+ // BLOCKS: call void {{.+}}* @__kmpc_fork_call({{.+}}, i32 1, {{.+}}* [[OMP_REGION:@.+]] to {{.+}}, i8* [[ARG]])
+#pragma omp parallel private(g)
+ {
+ // BLOCKS: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* %{{.+}}, i32* %{{.+}}, %{{.+}}* [[ARG:%.+]])
+ // BLOCKS: [[G_PRIVATE_ADDR:%.+]] = alloca i{{[0-9]+}},
+ // BLOCKS: store %{{.+}}* [[ARG]], %{{.+}}** [[ARG_REF:%.+]],
+ // BLOCKS: call void @__kmpc_barrier(
+ g = 1;
+ // BLOCKS: store volatile i{{[0-9]+}} 1, i{{[0-9]+}}* [[G_PRIVATE_ADDR]],
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: i{{[0-9]+}}* [[G_PRIVATE_ADDR]]
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: call void {{%.+}}(i8*
+ ^{
+ // BLOCKS: define {{.+}} void {{@.+}}(i8*
+ g = 2;
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: store volatile i{{[0-9]+}} 2, i{{[0-9]+}}*
+ // BLOCKS-NOT: [[G]]{{[[^:word:]]}}
+ // BLOCKS: ret
+ }();
+ }
+ }();
+ return 0;
+#else
S<float> test;
- int t_var;
+ int t_var = 0;
int vec[] = {1, 2};
S<float> s_arr[] = {1, 2};
S<float> var(3);
@@ -46,6 +117,7 @@
s_arr[0] = var;
}
return tmain<int>();
+#endif
}
// CHECK: define i{{[0-9]+}} @main()
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -3427,6 +3427,9 @@
TryCaptureKind Kind = TryCapture_Implicit,
SourceLocation EllipsisLoc = SourceLocation());
+ /// \brief Checks if the variable must be captured.
+ bool NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc);
+
/// \brief Given a variable, determine the type that a reference to that
/// variable will have in the given scope.
QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc);
@@ -7453,6 +7456,10 @@
void DestroyDataSharingAttributesStack();
ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op,
OpenMPClauseKind CKind);
+ /// \brief Checks if the specified variable is used in one of the private
+ /// clauses in OpenMP constructs.
+ bool IsOpenMPCapturedVar(VarDecl *VD);
+
public:
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc,
Expr *Op);
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h
+++ include/clang/AST/Expr.h
@@ -886,9 +886,9 @@
/// DeclRefExprBits.HasTemplateKWAndArgsInfo:
/// Specifies when this declaration reference expression has an explicit
/// C++ template keyword and/or template argument list.
-/// DeclRefExprBits.RefersToEnclosingLocal
+/// DeclRefExprBits.RefersToCapturedVariable
/// Specifies when this declaration reference expression (validly)
-/// refers to a local variable from a different function.
+/// refers to a captured variable.
class DeclRefExpr : public Expr {
/// \brief The declaration that we are referencing.
ValueDecl *D;
@@ -933,7 +933,7 @@
DeclRefExpr(const ASTContext &Ctx,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
- ValueDecl *D, bool refersToEnclosingLocal,
+ ValueDecl *D, bool RefersToCapturedVariable,
const DeclarationNameInfo &NameInfo,
NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
@@ -948,31 +948,31 @@
void computeDependence(const ASTContext &C);
public:
- DeclRefExpr(ValueDecl *D, bool refersToEnclosingLocal, QualType T,
+ DeclRefExpr(ValueDecl *D, bool RefersToCapturedVariable, QualType T,
ExprValueKind VK, SourceLocation L,
const DeclarationNameLoc &LocInfo = DeclarationNameLoc())
: Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
D(D), Loc(L), DNLoc(LocInfo) {
DeclRefExprBits.HasQualifier = 0;
DeclRefExprBits.HasTemplateKWAndArgsInfo = 0;
DeclRefExprBits.HasFoundDecl = 0;
DeclRefExprBits.HadMultipleCandidates = 0;
- DeclRefExprBits.RefersToEnclosingLocal = refersToEnclosingLocal;
+ DeclRefExprBits.RefersToCapturedVariable = RefersToCapturedVariable;
computeDependence(D->getASTContext());
}
static DeclRefExpr *
Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
- SourceLocation NameLoc, QualType T, ExprValueKind VK,
- NamedDecl *FoundD = nullptr,
+ SourceLocation TemplateKWLoc, ValueDecl *D,
+ bool RefersToCapturedVariable, SourceLocation NameLoc, QualType T,
+ ExprValueKind VK, NamedDecl *FoundD = nullptr,
const TemplateArgumentListInfo *TemplateArgs = nullptr);
static DeclRefExpr *
Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
- const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
- NamedDecl *FoundD = nullptr,
+ SourceLocation TemplateKWLoc, ValueDecl *D,
+ bool RefersToCapturedVariable, const DeclarationNameInfo &NameInfo,
+ QualType T, ExprValueKind VK, NamedDecl *FoundD = nullptr,
const TemplateArgumentListInfo *TemplateArgs = nullptr);
/// \brief Construct an empty declaration reference expression.
@@ -1144,10 +1144,9 @@
DeclRefExprBits.HadMultipleCandidates = V;
}
- /// Does this DeclRefExpr refer to a local declaration from an
- /// enclosing function scope?
- bool refersToEnclosingLocal() const {
- return DeclRefExprBits.RefersToEnclosingLocal;
+ /// Does this DeclRefExpr refer to a captured variable?
+ bool refersToCapturedVariable() const {
+ return DeclRefExprBits.RefersToCapturedVariable;
}
static bool classof(const Stmt *T) {
Index: include/clang/AST/Stmt.h
===================================================================
--- include/clang/AST/Stmt.h
+++ include/clang/AST/Stmt.h
@@ -212,7 +212,7 @@
unsigned HasTemplateKWAndArgsInfo : 1;
unsigned HasFoundDecl : 1;
unsigned HadMultipleCandidates : 1;
- unsigned RefersToEnclosingLocal : 1;
+ unsigned RefersToCapturedVariable : 1;
};
class CastExprBitfields {
Index: lib/Frontend/Rewrite/RewriteObjC.cpp
===================================================================
--- lib/Frontend/Rewrite/RewriteObjC.cpp
+++ lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -3671,16 +3671,12 @@
GetBlockDeclRefExprs(*CI);
}
// Handle specific things.
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
- if (DRE->refersToEnclosingLocal()) {
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
+ if (DRE->refersToCapturedVariable() ||
+ HasLocalVariableExternalStorage(DRE->getDecl()))
// FIXME: Handle enums.
- if (!isa<FunctionDecl>(DRE->getDecl()))
- BlockDeclRefs.push_back(DRE);
- if (HasLocalVariableExternalStorage(DRE->getDecl()))
- BlockDeclRefs.push_back(DRE);
- }
- }
-
+ BlockDeclRefs.push_back(DRE);
+
return;
}
@@ -3703,11 +3699,11 @@
}
// Handle specific things.
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
- if (DRE->refersToEnclosingLocal()) {
- if (!isa<FunctionDecl>(DRE->getDecl()) &&
- !InnerContexts.count(DRE->getDecl()->getDeclContext()))
+ if (DRE->refersToCapturedVariable() ||
+ HasLocalVariableExternalStorage(DRE->getDecl())) {
+ if (!InnerContexts.count(DRE->getDecl()->getDeclContext()))
InnerBlockDeclRefs.push_back(DRE);
- if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
+ if (VarDecl *Var = cast<VarDecl>(DRE->getDecl()))
if (Var->isFunctionOrMethodVarDecl())
ImportedLocalExternalDecls.insert(Var);
}
@@ -3865,7 +3861,8 @@
// Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR
// for each DeclRefExp where BYREFVAR is name of the variable.
ValueDecl *VD = DeclRefExp->getDecl();
- bool isArrow = DeclRefExp->refersToEnclosingLocal();
+ bool isArrow = DeclRefExp->refersToCapturedVariable() ||
+ HasLocalVariableExternalStorage(DeclRefExp->getDecl());
FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
SourceLocation(),
Index: lib/Frontend/Rewrite/RewriteModernObjC.cpp
===================================================================
--- lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -4563,16 +4563,12 @@
GetBlockDeclRefExprs(*CI);
}
// Handle specific things.
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
- if (DRE->refersToEnclosingLocal()) {
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
+ if (DRE->refersToCapturedVariable() ||
+ HasLocalVariableExternalStorage(DRE->getDecl()))
// FIXME: Handle enums.
- if (!isa<FunctionDecl>(DRE->getDecl()))
- BlockDeclRefs.push_back(DRE);
- if (HasLocalVariableExternalStorage(DRE->getDecl()))
- BlockDeclRefs.push_back(DRE);
- }
- }
-
+ BlockDeclRefs.push_back(DRE);
+
return;
}
@@ -4595,11 +4591,11 @@
}
// Handle specific things.
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
- if (DRE->refersToEnclosingLocal()) {
- if (!isa<FunctionDecl>(DRE->getDecl()) &&
- !InnerContexts.count(DRE->getDecl()->getDeclContext()))
+ if (DRE->refersToCapturedVariable() ||
+ HasLocalVariableExternalStorage(DRE->getDecl())) {
+ if (!InnerContexts.count(DRE->getDecl()->getDeclContext()))
InnerBlockDeclRefs.push_back(DRE);
- if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
+ if (VarDecl *Var = cast<VarDecl>(DRE->getDecl()))
if (Var->isFunctionOrMethodVarDecl())
ImportedLocalExternalDecls.insert(Var);
}
@@ -4776,7 +4772,8 @@
// Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR
// for each DeclRefExp where BYREFVAR is name of the variable.
ValueDecl *VD = DeclRefExp->getDecl();
- bool isArrow = DeclRefExp->refersToEnclosingLocal();
+ bool isArrow = DeclRefExp->refersToCapturedVariable() ||
+ HasLocalVariableExternalStorage(DeclRefExp->getDecl());
FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
SourceLocation(),
Index: lib/Analysis/BodyFarm.cpp
===================================================================
--- lib/Analysis/BodyFarm.cpp
+++ lib/Analysis/BodyFarm.cpp
@@ -115,7 +115,7 @@
/* QualifierLoc = */ NestedNameSpecifierLoc(),
/* TemplateKWLoc = */ SourceLocation(),
/* D = */ const_cast<VarDecl*>(D),
- /* isEnclosingLocal = */ false,
+ /* RefersToCapturedVariable = */ false,
/* NameLoc = */ SourceLocation(),
/* T = */ D->getType(),
/* VK = */ VK_LValue);
Index: lib/Sema/SemaOpenMP.cpp
===================================================================
--- lib/Sema/SemaOpenMP.cpp
+++ lib/Sema/SemaOpenMP.cpp
@@ -551,6 +551,19 @@
#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
+bool Sema::IsOpenMPCapturedVar(VarDecl *VD) {
+ assert(LangOpts.OpenMP && "OpenMP is not allowed");
+ if (DSAStack->getCurrentDirective() != OMPD_unknown) {
+ auto DVarPrivate = DSAStack->getTopDSA(VD, /*FromParent=*/false);
+ if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
+ return true;
+ DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(),
+ /*FromParent=*/false);
+ return DVarPrivate.CKind != OMPC_unknown;
+ }
+ return false;
+}
+
void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
@@ -4016,7 +4029,7 @@
auto VDPrivateRefExpr = DeclRefExpr::Create(
Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
/*TemplateKWLoc*/ SourceLocation(), VDPrivate,
- /*isEnclosingLocal*/ false, /*NameLoc*/ SourceLocation(), DE->getType(),
+ /*RefersToCapturedVariable*/ false, /*NameLoc*/ SourceLocation(), DE->getType(),
/*VK*/ VK_LValue);
DSAStack->addDSA(VD, DE, OMPC_private);
@@ -4236,10 +4249,9 @@
VD->getTypeSourceInfo(), /*S*/ SC_Auto);
CurContext->addHiddenDecl(VDInit);
VDInitRefExpr = DeclRefExpr::Create(
- Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
- /*TemplateKWLoc*/ SourceLocation(), VDInit,
- /*isEnclosingLocal*/ false, ELoc, Type,
- /*VK*/ VK_LValue);
+ Context, NestedNameSpecifierLoc(), SourceLocation(), VDInit,
+ /*RefersToCapturedVariable=*/true, ELoc, Type,
+ /*VK=*/VK_LValue);
VDInit->setIsUsed();
auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
InitializedEntity Entity = InitializedEntity::InitializeVariable(VDInit);
@@ -4252,8 +4264,14 @@
else
VDPrivate->setInit(Result.getAs<Expr>());
} else {
- AddInitializerToDecl(VDPrivate, DefaultLvalueConversion(DE).get(),
- /*DirectInit*/ false, /*TypeMayContainAuto*/ false);
+ AddInitializerToDecl(
+ VDPrivate, DefaultLvalueConversion(
+ DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
+ SourceLocation(), DE->getDecl(),
+ /*RefersToCapturedVariable=*/true,
+ DE->getExprLoc(), DE->getType(),
+ /*VK=*/VK_LValue)).get(),
+ /*DirectInit=*/false, /*TypeMayContainAuto=*/false);
}
if (VDPrivate->isInvalidDecl()) {
if (IsImplicitClause) {
@@ -4264,10 +4282,9 @@
}
CurContext->addDecl(VDPrivate);
auto VDPrivateRefExpr = DeclRefExpr::Create(
- Context, /*QualifierLoc*/ NestedNameSpecifierLoc(),
- /*TemplateKWLoc*/ SourceLocation(), VDPrivate,
- /*isEnclosingLocal*/ false, DE->getLocStart(), DE->getType(),
- /*VK*/ VK_LValue);
+ Context, NestedNameSpecifierLoc(), SourceLocation(), VDPrivate,
+ /*RefersToCapturedVariable=*/false, DE->getLocStart(), DE->getType(),
+ /*VK=*/VK_LValue);
DSAStack->addDSA(VD, DE, OMPC_firstprivate);
Vars.push_back(DE);
PrivateCopies.push_back(VDPrivateRefExpr);
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -10159,7 +10159,7 @@
QualType CaptureType = VD->getType();
const bool ByRef = C.getCaptureKind() == LCK_ByRef;
LSI->addCapture(VD, /*IsBlock*/false, ByRef,
- /*RefersToEnclosingLocal*/true, C.getLocation(),
+ /*RefersToCapturedVariable*/true, C.getLocation(),
/*EllipsisLoc*/C.isPackExpansion()
? C.getEllipsisLoc() : SourceLocation(),
CaptureType, /*Expr*/ nullptr);
Index: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -2447,7 +2447,7 @@
// - in a return statement in a function [where] ...
// ... the expression is the name of a non-volatile automatic object ...
DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParens());
- if (!DR || DR->refersToEnclosingLocal())
+ if (!DR || DR->refersToCapturedVariable())
return nullptr;
VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
if (!VD)
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -4858,7 +4858,7 @@
DeclRefExpr *DR = cast<DeclRefExpr>(E);
// If we leave the immediate function, the lifetime isn't about to end.
- if (DR->refersToEnclosingLocal())
+ if (DR->refersToCapturedVariable())
return nullptr;
if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl()))
@@ -5025,7 +5025,7 @@
DeclRefExpr *DR = cast<DeclRefExpr>(E);
// If we leave the immediate function, the lifetime isn't about to end.
- if (DR->refersToEnclosingLocal())
+ if (DR->refersToCapturedVariable())
return nullptr;
if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl())) {
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -1601,11 +1601,9 @@
}
}
- bool refersToEnclosingScope =
- (CurContext != D->getDeclContext() &&
- D->getDeclContext()->isFunctionOrMethod()) ||
- (isa<VarDecl>(D) &&
- cast<VarDecl>(D)->isInitCapture());
+ bool RefersToCapturedVariable =
+ isa<VarDecl>(D) &&
+ NeedToCaptureVariable(cast<VarDecl>(D), NameInfo.getLoc());
DeclRefExpr *E;
if (isa<VarTemplateSpecializationDecl>(D)) {
@@ -1615,15 +1613,15 @@
E = DeclRefExpr::Create(
Context,
SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(),
- VarSpec->getTemplateKeywordLoc(), D, refersToEnclosingScope,
+ VarSpec->getTemplateKeywordLoc(), D, RefersToCapturedVariable,
NameInfo.getLoc(), Ty, VK, FoundD, TemplateArgs);
} else {
assert(!TemplateArgs && "No template arguments for non-variable"
" template specialization references");
- E = DeclRefExpr::Create(
- Context,
- SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(),
- SourceLocation(), D, refersToEnclosingScope, NameInfo, Ty, VK, FoundD);
+ E = DeclRefExpr::Create(Context, SS ? SS->getWithLocInContext(Context)
+ : NestedNameSpecifierLoc(),
+ SourceLocation(), D, RefersToCapturedVariable,
+ NameInfo, Ty, VK, FoundD);
}
MarkDeclRefReferenced(E);
@@ -8462,7 +8460,7 @@
// Must be a reference to a declaration from an enclosing scope.
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
if (!DRE) return NCCK_None;
- if (!DRE->refersToEnclosingLocal()) return NCCK_None;
+ if (!DRE->refersToCapturedVariable()) return NCCK_None;
// The declaration must be a variable which is not declared 'const'.
VarDecl *var = dyn_cast<VarDecl>(DRE->getDecl());
@@ -11654,7 +11652,7 @@
const bool Diagnose, Sema &S) {
if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC) || isLambdaCallOperator(DC))
return getLambdaAwareParentOfDeclContext(DC);
- else {
+ else if (Var->hasLocalStorage()) {
if (Diagnose)
diagnoseUncapturableValueReference(S, Loc, Var, DC);
}
@@ -11822,7 +11820,7 @@
const bool BuildAndDiagnose,
QualType &CaptureType,
QualType &DeclRefType,
- const bool RefersToEnclosingLocal,
+ const bool RefersToCapturedVariable,
Sema &S) {
// By default, capture variables by reference.
@@ -11844,15 +11842,15 @@
Field->setAccess(AS_private);
RD->addDecl(Field);
- CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal,
+ CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToCapturedVariable,
DeclRefType, VK_LValue, Loc);
Var->setReferenced(true);
Var->markUsed(S.Context);
}
// Actually capture the variable.
if (BuildAndDiagnose)
- RSI->addCapture(Var, /*isBlock*/false, ByRef, RefersToEnclosingLocal, Loc,
+ RSI->addCapture(Var, /*isBlock*/false, ByRef, RefersToCapturedVariable, Loc,
SourceLocation(), CaptureType, CopyExpr);
@@ -11866,7 +11864,7 @@
VarDecl *Var, QualType FieldType,
QualType DeclRefType,
SourceLocation Loc,
- bool RefersToEnclosingLocal) {
+ bool RefersToCapturedVariable) {
CXXRecordDecl *Lambda = LSI->Lambda;
// Build the non-static data member.
@@ -11895,7 +11893,7 @@
// C++ [expr.prim.labda]p12:
// An entity captured by a lambda-expression is odr-used (3.2) in
// the scope containing the lambda-expression.
- Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal,
+ Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToCapturedVariable,
DeclRefType, VK_LValue, Loc);
Var->setReferenced(true);
Var->markUsed(S.Context);
@@ -11989,7 +11987,7 @@
const bool BuildAndDiagnose,
QualType &CaptureType,
QualType &DeclRefType,
- const bool RefersToEnclosingLocal,
+ const bool RefersToCapturedVariable,
const Sema::TryCaptureKind Kind,
SourceLocation EllipsisLoc,
const bool IsTopScope,
@@ -12063,7 +12061,7 @@
if (BuildAndDiagnose) {
ExprResult Result = addAsFieldToClosureType(S, LSI, Var,
CaptureType, DeclRefType, Loc,
- RefersToEnclosingLocal);
+ RefersToCapturedVariable);
if (!Result.isInvalid())
CopyExpr = Result.get();
}
@@ -12084,7 +12082,7 @@
// Add the capture.
if (BuildAndDiagnose)
- LSI->addCapture(Var, /*IsBlock=*/false, ByRef, RefersToEnclosingLocal,
+ LSI->addCapture(Var, /*IsBlock=*/false, ByRef, RefersToCapturedVariable,
Loc, EllipsisLoc, CaptureType, CopyExpr);
return true;
@@ -12096,7 +12094,7 @@
QualType &CaptureType,
QualType &DeclRefType,
const unsigned *const FunctionScopeIndexToStopAt) {
- bool Nested = false;
+ bool Nested = Var->isInitCapture();
DeclContext *DC = CurContext;
const unsigned MaxFunctionScopesIndex = FunctionScopeIndexToStopAt
@@ -12114,8 +12112,13 @@
// If the variable is declared in the current context (and is not an
// init-capture), there is no need to capture it.
- if (!Var->isInitCapture() && Var->getDeclContext() == DC) return true;
- if (!Var->hasLocalStorage()) return true;
+ if (!Nested && Var->getDeclContext() == DC) return true;
+
+ // Capture global variables if it is required to use private copy of this
+ // variable.
+ bool IsGlobal = !Var->hasLocalStorage();
+ if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedVar(Var)))
+ return true;
// Walk up the stack to determine whether we can capture the variable,
// performing the "simple" checks that don't depend on type. We stop when
@@ -12136,8 +12139,17 @@
ExprLoc,
BuildAndDiagnose,
*this);
- if (!ParentDC) return true;
-
+ // We need to check for the parent *first* because, if we *have*
+ // private-captured a global variable, we need to recursively capture it in
+ // intermediate blocks, lambdas, etc.
+ if (!ParentDC) {
+ if (IsGlobal) {
+ FunctionScopesIndex = MaxFunctionScopesIndex - 1;
+ break;
+ }
+ return true;
+ }
+
FunctionScopeInfo *FSI = FunctionScopes[FunctionScopesIndex];
CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FSI);
@@ -12363,6 +12375,14 @@
DeclRefType, nullptr);
}
+bool Sema::NeedToCaptureVariable(VarDecl *Var, SourceLocation Loc) {
+ QualType CaptureType;
+ QualType DeclRefType;
+ return !tryCaptureVariable(Var, Loc, TryCapture_Implicit, SourceLocation(),
+ /*BuildAndDiagnose=*/false, CaptureType,
+ DeclRefType, nullptr);
+}
+
QualType Sema::getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc) {
QualType CaptureType;
QualType DeclRefType;
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -4375,7 +4375,7 @@
Importer.Import(E->getQualifierLoc()),
Importer.Import(E->getTemplateKeywordLoc()),
ToD,
- E->refersToEnclosingLocal(),
+ E->refersToCapturedVariable(),
Importer.Import(E->getLocation()),
T, E->getValueKind(),
FoundD,
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -322,7 +322,7 @@
DeclRefExpr::DeclRefExpr(const ASTContext &Ctx,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
- ValueDecl *D, bool RefersToEnclosingLocal,
+ ValueDecl *D, bool RefersToCapturedVariable,
const DeclarationNameInfo &NameInfo,
NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
@@ -343,7 +343,7 @@
getInternalFoundDecl() = FoundD;
DeclRefExprBits.HasTemplateKWAndArgsInfo
= (TemplateArgs || TemplateKWLoc.isValid()) ? 1 : 0;
- DeclRefExprBits.RefersToEnclosingLocal = RefersToEnclosingLocal;
+ DeclRefExprBits.RefersToCapturedVariable = RefersToCapturedVariable;
if (TemplateArgs) {
bool Dependent = false;
bool InstantiationDependent = false;
@@ -367,23 +367,23 @@
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
ValueDecl *D,
- bool RefersToEnclosingLocal,
+ bool RefersToCapturedVariable,
SourceLocation NameLoc,
QualType T,
ExprValueKind VK,
NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs) {
return Create(Context, QualifierLoc, TemplateKWLoc, D,
- RefersToEnclosingLocal,
+ RefersToCapturedVariable,
DeclarationNameInfo(D->getDeclName(), NameLoc),
T, VK, FoundD, TemplateArgs);
}
DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
ValueDecl *D,
- bool RefersToEnclosingLocal,
+ bool RefersToCapturedVariable,
const DeclarationNameInfo &NameInfo,
QualType T,
ExprValueKind VK,
@@ -405,7 +405,7 @@
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
return new (Mem) DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D,
- RefersToEnclosingLocal,
+ RefersToCapturedVariable,
NameInfo, FoundD, TemplateArgs, T, VK);
}
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -182,6 +182,8 @@
/// \brief API for captured statement code generation.
class CGCapturedStmtInfo {
public:
+ explicit CGCapturedStmtInfo(CapturedRegionKind K = CR_Default)
+ : Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {}
explicit CGCapturedStmtInfo(const CapturedStmt &S,
CapturedRegionKind K = CR_Default)
: Kind(K), ThisValue(nullptr), CXXThisFieldDecl(nullptr) {
@@ -614,7 +616,6 @@
addPrivate(const VarDecl *LocalVD,
const std::function<llvm::Value *()> &PrivateGen) {
assert(PerformCleanup && "adding private to dead scope");
- assert(LocalVD->isLocalVarDecl() && "privatizing non-local variable");
if (SavedLocals.count(LocalVD) > 0) return false;
SavedLocals[LocalVD] = CGF.LocalDeclMap.lookup(LocalVD);
CGF.LocalDeclMap.erase(LocalVD);
Index: lib/CodeGen/CGStmtOpenMP.cpp
===================================================================
--- lib/CodeGen/CGStmtOpenMP.cpp
+++ lib/CodeGen/CGStmtOpenMP.cpp
@@ -20,6 +20,35 @@
using namespace clang;
using namespace CodeGen;
+namespace {
+/// \brief RAII for emitting code of CapturedStmt without function outlining.
+class InlinedOpenMPRegion {
+ CodeGenFunction &CGF;
+ CodeGenFunction::CGCapturedStmtInfo *PrevCapturedStmtInfo;
+ const Decl *StoredCurCodeDecl;
+
+ /// \brief A class to emit CapturedStmt construct as inlined statement without
+ /// generating a function for outlined code.
+ class CGInlinedOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo {
+ public:
+ CGInlinedOpenMPRegionInfo() : CGCapturedStmtInfo() {}
+ };
+
+public:
+ InlinedOpenMPRegion(CodeGenFunction &CGF, const Stmt *S)
+ : CGF(CGF), PrevCapturedStmtInfo(CGF.CapturedStmtInfo),
+ StoredCurCodeDecl(CGF.CurCodeDecl) {
+ CGF.CurCodeDecl = cast<CapturedStmt>(S)->getCapturedDecl();
+ CGF.CapturedStmtInfo = new CGInlinedOpenMPRegionInfo();
+ }
+ ~InlinedOpenMPRegion() {
+ delete CGF.CapturedStmtInfo;
+ CGF.CapturedStmtInfo = PrevCapturedStmtInfo;
+ CGF.CurCodeDecl = StoredCurCodeDecl;
+ }
+};
+} // namespace
+
//===----------------------------------------------------------------------===//
// OpenMP Directive Emission
//===----------------------------------------------------------------------===//
@@ -417,6 +446,7 @@
}
}
+ InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
RunCleanupsScope DirectiveScope(*this);
CGDebugInfo *DI = getDebugInfo();
@@ -505,8 +535,10 @@
CGM.getOpenMPRuntime().EmitOMPCriticalRegionStart(*this, Lock,
S.getLocStart());
{
+ InlinedOpenMPRegion Region(*this, S.getAssociatedStmt());
RunCleanupsScope Scope(*this);
- EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
+ EmitStmt(
+ cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
EnsureInsertPoint();
}
CGM.getOpenMPRuntime().EmitOMPCriticalRegionEnd(*this, Lock, S.getLocEnd());
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -1897,6 +1897,21 @@
QualType T = E->getType();
if (const auto *VD = dyn_cast<VarDecl>(ND)) {
+ // Check for captured variables.
+ if (E->refersToCapturedVariable()) {
+ if (auto *FD = LambdaCaptureFields.lookup(VD))
+ return EmitCapturedFieldLValue(*this, FD, CXXABIThisValue);
+ else if (CapturedStmtInfo) {
+ if (auto *V = LocalDeclMap.lookup(VD))
+ return MakeAddrLValue(V, T, Alignment);
+ else
+ return EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD),
+ CapturedStmtInfo->getContextValue());
+ } else
+ return MakeAddrLValue(GetAddrOfBlockDecl(VD, VD->hasAttr<BlocksAttr>()),
+ T, Alignment);
+ }
+
// Global Named registers access via intrinsics only
if (VD->getStorageClass() == SC_Register &&
VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
@@ -1947,21 +1962,6 @@
*this, VD, T, V, getTypes().ConvertTypeForMem(VD->getType()),
Alignment, E->getExprLoc());
- // Use special handling for lambdas.
- if (!V) {
- if (FieldDecl *FD = LambdaCaptureFields.lookup(VD)) {
- return EmitCapturedFieldLValue(*this, FD, CXXABIThisValue);
- } else if (CapturedStmtInfo) {
- if (const FieldDecl *FD = CapturedStmtInfo->lookup(VD))
- return EmitCapturedFieldLValue(*this, FD,
- CapturedStmtInfo->getContextValue());
- }
-
- assert(isa<BlockDecl>(CurCodeDecl) && E->refersToEnclosingLocal());
- return MakeAddrLValue(GetAddrOfBlockDecl(VD, isBlockVariable),
- T, Alignment);
- }
-
assert(V && "DeclRefExpr not entered in LocalDeclMap?");
if (isBlockVariable)
Index: lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1842,7 +1842,8 @@
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //RefersToEnclosingLocal
+ Abv->Add(
+ BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // RefersToCapturedVariable
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
DeclRefExprAbbrev = Stream.EmitAbbrev(Abv);
Index: lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -433,7 +433,7 @@
E->DeclRefExprBits.HasFoundDecl = Record[Idx++];
E->DeclRefExprBits.HasTemplateKWAndArgsInfo = Record[Idx++];
E->DeclRefExprBits.HadMultipleCandidates = Record[Idx++];
- E->DeclRefExprBits.RefersToEnclosingLocal = Record[Idx++];
+ E->DeclRefExprBits.RefersToCapturedVariable = Record[Idx++];
unsigned NumTemplateArgs = 0;
if (E->hasTemplateKWAndArgsInfo())
NumTemplateArgs = Record[Idx++];
Index: lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -344,7 +344,7 @@
Record.push_back(E->getDecl() != E->getFoundDecl());
Record.push_back(E->hasTemplateKWAndArgsInfo());
Record.push_back(E->hadMultipleCandidates());
- Record.push_back(E->refersToEnclosingLocal());
+ Record.push_back(E->refersToCapturedVariable());
if (E->hasTemplateKWAndArgsInfo()) {
unsigned NumTemplateArgs = E->getNumTemplateArgs();
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits