@@ -198,31 +198,50 @@ class SemaOpenACCClauseVisitor {
198198 Mods = CheckSingle (Mods, ValidKinds, OpenACCModifierKind::AlwaysOut);
199199 Mods = CheckSingle (Mods, ValidKinds, OpenACCModifierKind::Readonly);
200200 Mods = CheckSingle (Mods, ValidKinds, OpenACCModifierKind::Zero);
201+ Mods = CheckSingle (Mods, ValidKinds, OpenACCModifierKind::Capture);
201202 return Mods;
202203 };
203204
205+ // The 'capture' modifier is only valid on copyin, copyout, and create on
206+ // structured data or compute constructs (which also includes combined).
207+ bool IsStructuredDataOrCompute =
208+ Clause.getDirectiveKind () == OpenACCDirectiveKind::Data ||
209+ isOpenACCComputeDirectiveKind (Clause.getDirectiveKind ()) ||
210+ isOpenACCCombinedDirectiveKind (Clause.getDirectiveKind ());
211+
204212 switch (Clause.getClauseKind ()) {
205213 default :
206214 llvm_unreachable (" Only for copy, copyin, copyout, create" );
207215 case OpenACCClauseKind::Copy:
208216 case OpenACCClauseKind::PCopy:
209217 case OpenACCClauseKind::PresentOrCopy:
218+ // COPY: Capture always
210219 return Check (OpenACCModifierKind::Always | OpenACCModifierKind::AlwaysIn |
211- OpenACCModifierKind::AlwaysOut);
220+ OpenACCModifierKind::AlwaysOut |
221+ OpenACCModifierKind::Capture);
212222 case OpenACCClauseKind::CopyIn:
213223 case OpenACCClauseKind::PCopyIn:
214224 case OpenACCClauseKind::PresentOrCopyIn:
225+ // COPYIN: Capture only struct.data & compute
215226 return Check (OpenACCModifierKind::Always | OpenACCModifierKind::AlwaysIn |
216- OpenACCModifierKind::Readonly);
227+ OpenACCModifierKind::Readonly |
228+ (IsStructuredDataOrCompute ? OpenACCModifierKind::Capture
229+ : OpenACCModifierKind::Invalid));
217230 case OpenACCClauseKind::CopyOut:
218231 case OpenACCClauseKind::PCopyOut:
219232 case OpenACCClauseKind::PresentOrCopyOut:
233+ // COPYOUT: Capture only struct.data & compute
220234 return Check (OpenACCModifierKind::Always | OpenACCModifierKind::AlwaysIn |
221- OpenACCModifierKind::Zero);
235+ OpenACCModifierKind::Zero |
236+ (IsStructuredDataOrCompute ? OpenACCModifierKind::Capture
237+ : OpenACCModifierKind::Invalid));
222238 case OpenACCClauseKind::Create:
223239 case OpenACCClauseKind::PCreate:
224240 case OpenACCClauseKind::PresentOrCreate:
225- return Check (OpenACCModifierKind::Zero);
241+ // CREATE: Capture only struct.data & compute
242+ return Check (OpenACCModifierKind::Zero |
243+ (IsStructuredDataOrCompute ? OpenACCModifierKind::Capture
244+ : OpenACCModifierKind::Invalid));
226245 }
227246 llvm_unreachable (" didn't return from switch above?" );
228247 }
0 commit comments