summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp52
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h3
2 files changed, 26 insertions, 29 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index d4fd3b5178d..f207a4f7f8d 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -2102,46 +2102,35 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
}
}
-static LValue InitCapturedStruct(CodeGenFunction &CGF, const CapturedStmt &S) {
+LValue CodeGenFunction::InitCapturedStruct(const CapturedStmt &S) {
const RecordDecl *RD = S.getCapturedRecordDecl();
- QualType RecordTy = CGF.getContext().getRecordType(RD);
+ QualType RecordTy = getContext().getRecordType(RD);
// Initialize the captured struct.
- LValue SlotLV = CGF.MakeNaturalAlignAddrLValue(
- CGF.CreateMemTemp(RecordTy, "agg.captured"), RecordTy);
+ LValue SlotLV = MakeNaturalAlignAddrLValue(
+ CreateMemTemp(RecordTy, "agg.captured"), RecordTy);
RecordDecl::field_iterator CurField = RD->field_begin();
for (CapturedStmt::capture_init_iterator I = S.capture_init_begin(),
E = S.capture_init_end();
I != E; ++I, ++CurField) {
- LValue LV = CGF.EmitLValueForFieldInitialization(SlotLV, *CurField);
- CGF.EmitInitializerForField(*CurField, LV, *I, None);
+ LValue LV = EmitLValueForFieldInitialization(SlotLV, *CurField);
+ if (CurField->hasCapturedVLAType()) {
+ auto VAT = CurField->getCapturedVLAType();
+ EmitStoreThroughLValue(RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
+ } else {
+ EmitInitializerForField(*CurField, LV, *I, None);
+ }
}
return SlotLV;
}
-static void InitVLACaptures(CodeGenFunction &CGF, const CapturedStmt &S) {
- for (auto &C : S.captures()) {
- if (C.capturesVariable()) {
- QualType QTy;
- auto VD = C.getCapturedVar();
- if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD))
- QTy = PVD->getOriginalType();
- else
- QTy = VD->getType();
- if (QTy->isVariablyModifiedType()) {
- CGF.EmitVariablyModifiedType(QTy);
- }
- }
- }
-}
-
/// Generate an outlined function for the body of a CapturedStmt, store any
/// captured variables into the captured struct, and call the outlined function.
llvm::Function *
CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K) {
- LValue CapStruct = InitCapturedStruct(*this, S);
+ LValue CapStruct = InitCapturedStruct(S);
// Emit the CapturedDecl
CodeGenFunction CGF(CGM, true);
@@ -2157,7 +2146,7 @@ CodeGenFunction::EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K) {
llvm::Value *
CodeGenFunction::GenerateCapturedStmtArgument(const CapturedStmt &S) {
- LValue CapStruct = InitCapturedStruct(*this, S);
+ LValue CapStruct = InitCapturedStruct(S);
return CapStruct.getAddress();
}
@@ -2198,14 +2187,21 @@ CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) {
CapturedStmtInfo->setContextValue(Builder.CreateLoad(DeclPtr));
// Initialize variable-length arrays.
- InitVLACaptures(*this, S);
+ LValue Base = MakeNaturalAlignAddrLValue(CapturedStmtInfo->getContextValue(),
+ Ctx.getTagDeclType(RD));
+ for (auto *FD : RD->fields()) {
+ if (FD->hasCapturedVLAType()) {
+ auto *ExprArg = EmitLoadOfLValue(EmitLValueForField(Base, FD),
+ S.getLocStart()).getScalarVal();
+ auto VAT = FD->getCapturedVLAType();
+ VLASizeMap[VAT->getSizeExpr()] = ExprArg;
+ }
+ }
// If 'this' is captured, load it into CXXThisValue.
if (CapturedStmtInfo->isCXXThisExprCaptured()) {
FieldDecl *FD = CapturedStmtInfo->getThisFieldDecl();
- LValue LV = MakeNaturalAlignAddrLValue(CapturedStmtInfo->getContextValue(),
- Ctx.getTagDeclType(RD));
- LValue ThisLValue = EmitLValueForField(LV, FD);
+ LValue ThisLValue = EmitLValueForField(Base, FD);
CXXThisValue = EmitLoadOfLValue(ThisLValue, Loc).getScalarVal();
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 66f3fcecff7..eb3e6566336 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -193,7 +193,7 @@ public:
I != E; ++I, ++Field) {
if (I->capturesThis())
CXXThisFieldDecl = *Field;
- else
+ else if (I->capturesVariable())
CaptureFields[I->getCapturedVar()] = *Field;
}
}
@@ -2002,6 +2002,7 @@ public:
void EmitCXXForRangeStmt(const CXXForRangeStmt &S,
ArrayRef<const Attr *> Attrs = None);
+ LValue InitCapturedStruct(const CapturedStmt &S);
llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K);
void GenerateCapturedStmtFunctionProlog(const CapturedStmt &S);
llvm::Function *GenerateCapturedStmtFunctionEpilog(const CapturedStmt &S);
OpenPOWER on IntegriCloud