1*2c75bda4Serichkeane //===--- SemaOpenACCClause.cpp - Semantic Analysis for OpenACC clause -----===// 2*2c75bda4Serichkeane // 3*2c75bda4Serichkeane // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2c75bda4Serichkeane // See https://llvm.org/LICENSE.txt for license information. 5*2c75bda4Serichkeane // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*2c75bda4Serichkeane // 7*2c75bda4Serichkeane //===----------------------------------------------------------------------===// 8*2c75bda4Serichkeane /// \file 9*2c75bda4Serichkeane /// This file implements semantic analysis for OpenACC clauses. 10*2c75bda4Serichkeane /// 11*2c75bda4Serichkeane //===----------------------------------------------------------------------===// 12*2c75bda4Serichkeane 13*2c75bda4Serichkeane #include "clang/AST/OpenACCClause.h" 14*2c75bda4Serichkeane #include "clang/AST/DeclCXX.h" 15*2c75bda4Serichkeane #include "clang/Basic/DiagnosticSema.h" 16*2c75bda4Serichkeane #include "clang/Basic/OpenACCKinds.h" 17*2c75bda4Serichkeane #include "clang/Sema/SemaOpenACC.h" 18*2c75bda4Serichkeane 19*2c75bda4Serichkeane using namespace clang; 20*2c75bda4Serichkeane 21*2c75bda4Serichkeane namespace { 22*2c75bda4Serichkeane bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind, 23*2c75bda4Serichkeane OpenACCClauseKind ClauseKind) { 24*2c75bda4Serichkeane switch (ClauseKind) { 25*2c75bda4Serichkeane // FIXME: For each clause as we implement them, we can add the 26*2c75bda4Serichkeane // 'legalization' list here. 27*2c75bda4Serichkeane case OpenACCClauseKind::Default: 28*2c75bda4Serichkeane switch (DirectiveKind) { 29*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 30*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 31*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 32*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 33*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 34*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 35*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 36*2c75bda4Serichkeane return true; 37*2c75bda4Serichkeane default: 38*2c75bda4Serichkeane return false; 39*2c75bda4Serichkeane } 40*2c75bda4Serichkeane case OpenACCClauseKind::If: 41*2c75bda4Serichkeane switch (DirectiveKind) { 42*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 43*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 44*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 45*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 46*2c75bda4Serichkeane case OpenACCDirectiveKind::EnterData: 47*2c75bda4Serichkeane case OpenACCDirectiveKind::ExitData: 48*2c75bda4Serichkeane case OpenACCDirectiveKind::HostData: 49*2c75bda4Serichkeane case OpenACCDirectiveKind::Init: 50*2c75bda4Serichkeane case OpenACCDirectiveKind::Shutdown: 51*2c75bda4Serichkeane case OpenACCDirectiveKind::Set: 52*2c75bda4Serichkeane case OpenACCDirectiveKind::Update: 53*2c75bda4Serichkeane case OpenACCDirectiveKind::Wait: 54*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 55*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 56*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 57*2c75bda4Serichkeane return true; 58*2c75bda4Serichkeane default: 59*2c75bda4Serichkeane return false; 60*2c75bda4Serichkeane } 61*2c75bda4Serichkeane case OpenACCClauseKind::Self: 62*2c75bda4Serichkeane switch (DirectiveKind) { 63*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 64*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 65*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 66*2c75bda4Serichkeane case OpenACCDirectiveKind::Update: 67*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 68*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 69*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 70*2c75bda4Serichkeane return true; 71*2c75bda4Serichkeane default: 72*2c75bda4Serichkeane return false; 73*2c75bda4Serichkeane } 74*2c75bda4Serichkeane case OpenACCClauseKind::NumGangs: 75*2c75bda4Serichkeane case OpenACCClauseKind::NumWorkers: 76*2c75bda4Serichkeane case OpenACCClauseKind::VectorLength: 77*2c75bda4Serichkeane switch (DirectiveKind) { 78*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 79*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 80*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 81*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 82*2c75bda4Serichkeane return true; 83*2c75bda4Serichkeane default: 84*2c75bda4Serichkeane return false; 85*2c75bda4Serichkeane } 86*2c75bda4Serichkeane case OpenACCClauseKind::FirstPrivate: 87*2c75bda4Serichkeane switch (DirectiveKind) { 88*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 89*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 90*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 91*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 92*2c75bda4Serichkeane return true; 93*2c75bda4Serichkeane default: 94*2c75bda4Serichkeane return false; 95*2c75bda4Serichkeane } 96*2c75bda4Serichkeane case OpenACCClauseKind::Private: 97*2c75bda4Serichkeane switch (DirectiveKind) { 98*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 99*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 100*2c75bda4Serichkeane case OpenACCDirectiveKind::Loop: 101*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 102*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 103*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 104*2c75bda4Serichkeane return true; 105*2c75bda4Serichkeane default: 106*2c75bda4Serichkeane return false; 107*2c75bda4Serichkeane } 108*2c75bda4Serichkeane case OpenACCClauseKind::NoCreate: 109*2c75bda4Serichkeane switch (DirectiveKind) { 110*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 111*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 112*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 113*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 114*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 115*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 116*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 117*2c75bda4Serichkeane return true; 118*2c75bda4Serichkeane default: 119*2c75bda4Serichkeane return false; 120*2c75bda4Serichkeane } 121*2c75bda4Serichkeane case OpenACCClauseKind::Present: 122*2c75bda4Serichkeane switch (DirectiveKind) { 123*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 124*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 125*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 126*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 127*2c75bda4Serichkeane case OpenACCDirectiveKind::Declare: 128*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 129*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 130*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 131*2c75bda4Serichkeane return true; 132*2c75bda4Serichkeane default: 133*2c75bda4Serichkeane return false; 134*2c75bda4Serichkeane } 135*2c75bda4Serichkeane 136*2c75bda4Serichkeane case OpenACCClauseKind::Copy: 137*2c75bda4Serichkeane case OpenACCClauseKind::PCopy: 138*2c75bda4Serichkeane case OpenACCClauseKind::PresentOrCopy: 139*2c75bda4Serichkeane switch (DirectiveKind) { 140*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 141*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 142*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 143*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 144*2c75bda4Serichkeane case OpenACCDirectiveKind::Declare: 145*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 146*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 147*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 148*2c75bda4Serichkeane return true; 149*2c75bda4Serichkeane default: 150*2c75bda4Serichkeane return false; 151*2c75bda4Serichkeane } 152*2c75bda4Serichkeane case OpenACCClauseKind::CopyIn: 153*2c75bda4Serichkeane case OpenACCClauseKind::PCopyIn: 154*2c75bda4Serichkeane case OpenACCClauseKind::PresentOrCopyIn: 155*2c75bda4Serichkeane switch (DirectiveKind) { 156*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 157*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 158*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 159*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 160*2c75bda4Serichkeane case OpenACCDirectiveKind::EnterData: 161*2c75bda4Serichkeane case OpenACCDirectiveKind::Declare: 162*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 163*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 164*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 165*2c75bda4Serichkeane return true; 166*2c75bda4Serichkeane default: 167*2c75bda4Serichkeane return false; 168*2c75bda4Serichkeane } 169*2c75bda4Serichkeane case OpenACCClauseKind::CopyOut: 170*2c75bda4Serichkeane case OpenACCClauseKind::PCopyOut: 171*2c75bda4Serichkeane case OpenACCClauseKind::PresentOrCopyOut: 172*2c75bda4Serichkeane switch (DirectiveKind) { 173*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 174*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 175*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 176*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 177*2c75bda4Serichkeane case OpenACCDirectiveKind::ExitData: 178*2c75bda4Serichkeane case OpenACCDirectiveKind::Declare: 179*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 180*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 181*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 182*2c75bda4Serichkeane return true; 183*2c75bda4Serichkeane default: 184*2c75bda4Serichkeane return false; 185*2c75bda4Serichkeane } 186*2c75bda4Serichkeane case OpenACCClauseKind::Create: 187*2c75bda4Serichkeane case OpenACCClauseKind::PCreate: 188*2c75bda4Serichkeane case OpenACCClauseKind::PresentOrCreate: 189*2c75bda4Serichkeane switch (DirectiveKind) { 190*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 191*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 192*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 193*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 194*2c75bda4Serichkeane case OpenACCDirectiveKind::EnterData: 195*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 196*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 197*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 198*2c75bda4Serichkeane return true; 199*2c75bda4Serichkeane default: 200*2c75bda4Serichkeane return false; 201*2c75bda4Serichkeane } 202*2c75bda4Serichkeane 203*2c75bda4Serichkeane case OpenACCClauseKind::Attach: 204*2c75bda4Serichkeane switch (DirectiveKind) { 205*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 206*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 207*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 208*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 209*2c75bda4Serichkeane case OpenACCDirectiveKind::EnterData: 210*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 211*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 212*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 213*2c75bda4Serichkeane return true; 214*2c75bda4Serichkeane default: 215*2c75bda4Serichkeane return false; 216*2c75bda4Serichkeane } 217*2c75bda4Serichkeane case OpenACCClauseKind::DevicePtr: 218*2c75bda4Serichkeane switch (DirectiveKind) { 219*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 220*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 221*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 222*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 223*2c75bda4Serichkeane case OpenACCDirectiveKind::Declare: 224*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 225*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 226*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 227*2c75bda4Serichkeane return true; 228*2c75bda4Serichkeane default: 229*2c75bda4Serichkeane return false; 230*2c75bda4Serichkeane } 231*2c75bda4Serichkeane case OpenACCClauseKind::Async: 232*2c75bda4Serichkeane switch (DirectiveKind) { 233*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 234*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 235*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 236*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 237*2c75bda4Serichkeane case OpenACCDirectiveKind::EnterData: 238*2c75bda4Serichkeane case OpenACCDirectiveKind::ExitData: 239*2c75bda4Serichkeane case OpenACCDirectiveKind::Set: 240*2c75bda4Serichkeane case OpenACCDirectiveKind::Update: 241*2c75bda4Serichkeane case OpenACCDirectiveKind::Wait: 242*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 243*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 244*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 245*2c75bda4Serichkeane return true; 246*2c75bda4Serichkeane default: 247*2c75bda4Serichkeane return false; 248*2c75bda4Serichkeane } 249*2c75bda4Serichkeane case OpenACCClauseKind::Wait: 250*2c75bda4Serichkeane switch (DirectiveKind) { 251*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 252*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 253*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 254*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 255*2c75bda4Serichkeane case OpenACCDirectiveKind::EnterData: 256*2c75bda4Serichkeane case OpenACCDirectiveKind::ExitData: 257*2c75bda4Serichkeane case OpenACCDirectiveKind::Update: 258*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 259*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 260*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 261*2c75bda4Serichkeane return true; 262*2c75bda4Serichkeane default: 263*2c75bda4Serichkeane return false; 264*2c75bda4Serichkeane } 265*2c75bda4Serichkeane 266*2c75bda4Serichkeane case OpenACCClauseKind::Seq: 267*2c75bda4Serichkeane switch (DirectiveKind) { 268*2c75bda4Serichkeane case OpenACCDirectiveKind::Loop: 269*2c75bda4Serichkeane case OpenACCDirectiveKind::Routine: 270*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 271*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 272*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 273*2c75bda4Serichkeane return true; 274*2c75bda4Serichkeane default: 275*2c75bda4Serichkeane return false; 276*2c75bda4Serichkeane } 277*2c75bda4Serichkeane 278*2c75bda4Serichkeane case OpenACCClauseKind::Independent: 279*2c75bda4Serichkeane case OpenACCClauseKind::Auto: 280*2c75bda4Serichkeane switch (DirectiveKind) { 281*2c75bda4Serichkeane case OpenACCDirectiveKind::Loop: 282*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 283*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 284*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 285*2c75bda4Serichkeane return true; 286*2c75bda4Serichkeane default: 287*2c75bda4Serichkeane return false; 288*2c75bda4Serichkeane } 289*2c75bda4Serichkeane 290*2c75bda4Serichkeane case OpenACCClauseKind::Reduction: 291*2c75bda4Serichkeane switch (DirectiveKind) { 292*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 293*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 294*2c75bda4Serichkeane case OpenACCDirectiveKind::Loop: 295*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 296*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 297*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 298*2c75bda4Serichkeane return true; 299*2c75bda4Serichkeane default: 300*2c75bda4Serichkeane return false; 301*2c75bda4Serichkeane } 302*2c75bda4Serichkeane 303*2c75bda4Serichkeane case OpenACCClauseKind::DeviceType: 304*2c75bda4Serichkeane case OpenACCClauseKind::DType: 305*2c75bda4Serichkeane switch (DirectiveKind) { 306*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 307*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 308*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 309*2c75bda4Serichkeane case OpenACCDirectiveKind::Data: 310*2c75bda4Serichkeane case OpenACCDirectiveKind::Init: 311*2c75bda4Serichkeane case OpenACCDirectiveKind::Shutdown: 312*2c75bda4Serichkeane case OpenACCDirectiveKind::Set: 313*2c75bda4Serichkeane case OpenACCDirectiveKind::Update: 314*2c75bda4Serichkeane case OpenACCDirectiveKind::Loop: 315*2c75bda4Serichkeane case OpenACCDirectiveKind::Routine: 316*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 317*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 318*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 319*2c75bda4Serichkeane return true; 320*2c75bda4Serichkeane default: 321*2c75bda4Serichkeane return false; 322*2c75bda4Serichkeane } 323*2c75bda4Serichkeane 324*2c75bda4Serichkeane case OpenACCClauseKind::Collapse: { 325*2c75bda4Serichkeane switch (DirectiveKind) { 326*2c75bda4Serichkeane case OpenACCDirectiveKind::Loop: 327*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 328*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 329*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 330*2c75bda4Serichkeane return true; 331*2c75bda4Serichkeane default: 332*2c75bda4Serichkeane return false; 333*2c75bda4Serichkeane } 334*2c75bda4Serichkeane } 335*2c75bda4Serichkeane case OpenACCClauseKind::Tile: { 336*2c75bda4Serichkeane switch (DirectiveKind) { 337*2c75bda4Serichkeane case OpenACCDirectiveKind::Loop: 338*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 339*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 340*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 341*2c75bda4Serichkeane return true; 342*2c75bda4Serichkeane default: 343*2c75bda4Serichkeane return false; 344*2c75bda4Serichkeane } 345*2c75bda4Serichkeane } 346*2c75bda4Serichkeane 347*2c75bda4Serichkeane case OpenACCClauseKind::Gang: { 348*2c75bda4Serichkeane switch (DirectiveKind) { 349*2c75bda4Serichkeane case OpenACCDirectiveKind::Loop: 350*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 351*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 352*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 353*2c75bda4Serichkeane case OpenACCDirectiveKind::Routine: 354*2c75bda4Serichkeane return true; 355*2c75bda4Serichkeane default: 356*2c75bda4Serichkeane return false; 357*2c75bda4Serichkeane } 358*2c75bda4Serichkeane case OpenACCClauseKind::Worker: { 359*2c75bda4Serichkeane switch (DirectiveKind) { 360*2c75bda4Serichkeane case OpenACCDirectiveKind::Loop: 361*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 362*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 363*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 364*2c75bda4Serichkeane case OpenACCDirectiveKind::Routine: 365*2c75bda4Serichkeane return true; 366*2c75bda4Serichkeane default: 367*2c75bda4Serichkeane return false; 368*2c75bda4Serichkeane } 369*2c75bda4Serichkeane } 370*2c75bda4Serichkeane case OpenACCClauseKind::Vector: { 371*2c75bda4Serichkeane switch (DirectiveKind) { 372*2c75bda4Serichkeane case OpenACCDirectiveKind::Loop: 373*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 374*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 375*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 376*2c75bda4Serichkeane case OpenACCDirectiveKind::Routine: 377*2c75bda4Serichkeane return true; 378*2c75bda4Serichkeane default: 379*2c75bda4Serichkeane return false; 380*2c75bda4Serichkeane } 381*2c75bda4Serichkeane } 382*2c75bda4Serichkeane case OpenACCClauseKind::Finalize: { 383*2c75bda4Serichkeane switch (DirectiveKind) { 384*2c75bda4Serichkeane case OpenACCDirectiveKind::ExitData: 385*2c75bda4Serichkeane return true; 386*2c75bda4Serichkeane default: 387*2c75bda4Serichkeane return false; 388*2c75bda4Serichkeane } 389*2c75bda4Serichkeane } 390*2c75bda4Serichkeane case OpenACCClauseKind::IfPresent: { 391*2c75bda4Serichkeane switch (DirectiveKind) { 392*2c75bda4Serichkeane case OpenACCDirectiveKind::HostData: 393*2c75bda4Serichkeane case OpenACCDirectiveKind::Update: 394*2c75bda4Serichkeane return true; 395*2c75bda4Serichkeane default: 396*2c75bda4Serichkeane return false; 397*2c75bda4Serichkeane } 398*2c75bda4Serichkeane } 399*2c75bda4Serichkeane case OpenACCClauseKind::Delete: { 400*2c75bda4Serichkeane switch (DirectiveKind) { 401*2c75bda4Serichkeane case OpenACCDirectiveKind::ExitData: 402*2c75bda4Serichkeane return true; 403*2c75bda4Serichkeane default: 404*2c75bda4Serichkeane return false; 405*2c75bda4Serichkeane } 406*2c75bda4Serichkeane } 407*2c75bda4Serichkeane 408*2c75bda4Serichkeane case OpenACCClauseKind::Detach: { 409*2c75bda4Serichkeane switch (DirectiveKind) { 410*2c75bda4Serichkeane case OpenACCDirectiveKind::ExitData: 411*2c75bda4Serichkeane return true; 412*2c75bda4Serichkeane default: 413*2c75bda4Serichkeane return false; 414*2c75bda4Serichkeane } 415*2c75bda4Serichkeane } 416*2c75bda4Serichkeane 417*2c75bda4Serichkeane case OpenACCClauseKind::DeviceNum: { 418*2c75bda4Serichkeane switch (DirectiveKind) { 419*2c75bda4Serichkeane case OpenACCDirectiveKind::Init: 420*2c75bda4Serichkeane case OpenACCDirectiveKind::Shutdown: 421*2c75bda4Serichkeane case OpenACCDirectiveKind::Set: 422*2c75bda4Serichkeane return true; 423*2c75bda4Serichkeane default: 424*2c75bda4Serichkeane return false; 425*2c75bda4Serichkeane } 426*2c75bda4Serichkeane } 427*2c75bda4Serichkeane 428*2c75bda4Serichkeane case OpenACCClauseKind::UseDevice: { 429*2c75bda4Serichkeane switch (DirectiveKind) { 430*2c75bda4Serichkeane case OpenACCDirectiveKind::HostData: 431*2c75bda4Serichkeane return true; 432*2c75bda4Serichkeane default: 433*2c75bda4Serichkeane return false; 434*2c75bda4Serichkeane } 435*2c75bda4Serichkeane } 436*2c75bda4Serichkeane case OpenACCClauseKind::DefaultAsync: { 437*2c75bda4Serichkeane switch (DirectiveKind) { 438*2c75bda4Serichkeane case OpenACCDirectiveKind::Set: 439*2c75bda4Serichkeane return true; 440*2c75bda4Serichkeane default: 441*2c75bda4Serichkeane return false; 442*2c75bda4Serichkeane } 443*2c75bda4Serichkeane } 444*2c75bda4Serichkeane case OpenACCClauseKind::Device: { 445*2c75bda4Serichkeane switch (DirectiveKind) { 446*2c75bda4Serichkeane case OpenACCDirectiveKind::Update: 447*2c75bda4Serichkeane return true; 448*2c75bda4Serichkeane default: 449*2c75bda4Serichkeane return false; 450*2c75bda4Serichkeane } 451*2c75bda4Serichkeane } 452*2c75bda4Serichkeane case OpenACCClauseKind::Host: { 453*2c75bda4Serichkeane switch (DirectiveKind) { 454*2c75bda4Serichkeane case OpenACCDirectiveKind::Update: 455*2c75bda4Serichkeane return true; 456*2c75bda4Serichkeane default: 457*2c75bda4Serichkeane return false; 458*2c75bda4Serichkeane } 459*2c75bda4Serichkeane } 460*2c75bda4Serichkeane } 461*2c75bda4Serichkeane 462*2c75bda4Serichkeane default: 463*2c75bda4Serichkeane // Do nothing so we can go to the 'unimplemented' diagnostic instead. 464*2c75bda4Serichkeane return true; 465*2c75bda4Serichkeane } 466*2c75bda4Serichkeane llvm_unreachable("Invalid clause kind"); 467*2c75bda4Serichkeane } 468*2c75bda4Serichkeane 469*2c75bda4Serichkeane bool checkAlreadyHasClauseOfKind( 470*2c75bda4Serichkeane SemaOpenACC &S, ArrayRef<const OpenACCClause *> ExistingClauses, 471*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 472*2c75bda4Serichkeane const auto *Itr = llvm::find_if(ExistingClauses, [&](const OpenACCClause *C) { 473*2c75bda4Serichkeane return C->getClauseKind() == Clause.getClauseKind(); 474*2c75bda4Serichkeane }); 475*2c75bda4Serichkeane if (Itr != ExistingClauses.end()) { 476*2c75bda4Serichkeane S.Diag(Clause.getBeginLoc(), diag::err_acc_duplicate_clause_disallowed) 477*2c75bda4Serichkeane << Clause.getDirectiveKind() << Clause.getClauseKind(); 478*2c75bda4Serichkeane S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 479*2c75bda4Serichkeane return true; 480*2c75bda4Serichkeane } 481*2c75bda4Serichkeane return false; 482*2c75bda4Serichkeane } 483*2c75bda4Serichkeane bool checkValidAfterDeviceType( 484*2c75bda4Serichkeane SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause, 485*2c75bda4Serichkeane const SemaOpenACC::OpenACCParsedClause &NewClause) { 486*2c75bda4Serichkeane // This is implemented for everything but 'routine', so treat as 'fine' for 487*2c75bda4Serichkeane // that. 488*2c75bda4Serichkeane if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Routine) 489*2c75bda4Serichkeane return false; 490*2c75bda4Serichkeane 491*2c75bda4Serichkeane // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are 492*2c75bda4Serichkeane // default clauses. Clauses that follow a device_type clause up to the end of 493*2c75bda4Serichkeane // the directive or up to the next device_type clause are device-specific 494*2c75bda4Serichkeane // clauses for the device types specified in the device_type argument. 495*2c75bda4Serichkeane // 496*2c75bda4Serichkeane // The above implies that despite what the individual text says, these are 497*2c75bda4Serichkeane // valid. 498*2c75bda4Serichkeane if (NewClause.getClauseKind() == OpenACCClauseKind::DType || 499*2c75bda4Serichkeane NewClause.getClauseKind() == OpenACCClauseKind::DeviceType) 500*2c75bda4Serichkeane return false; 501*2c75bda4Serichkeane 502*2c75bda4Serichkeane // Implement check from OpenACC3.3: section 2.5.4: 503*2c75bda4Serichkeane // Only the async, wait, num_gangs, num_workers, and vector_length clauses may 504*2c75bda4Serichkeane // follow a device_type clause. 505*2c75bda4Serichkeane if (isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind())) { 506*2c75bda4Serichkeane switch (NewClause.getClauseKind()) { 507*2c75bda4Serichkeane case OpenACCClauseKind::Async: 508*2c75bda4Serichkeane case OpenACCClauseKind::Wait: 509*2c75bda4Serichkeane case OpenACCClauseKind::NumGangs: 510*2c75bda4Serichkeane case OpenACCClauseKind::NumWorkers: 511*2c75bda4Serichkeane case OpenACCClauseKind::VectorLength: 512*2c75bda4Serichkeane return false; 513*2c75bda4Serichkeane default: 514*2c75bda4Serichkeane break; 515*2c75bda4Serichkeane } 516*2c75bda4Serichkeane } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) { 517*2c75bda4Serichkeane // Implement check from OpenACC3.3: section 2.9: 518*2c75bda4Serichkeane // Only the collapse, gang, worker, vector, seq, independent, auto, and tile 519*2c75bda4Serichkeane // clauses may follow a device_type clause. 520*2c75bda4Serichkeane switch (NewClause.getClauseKind()) { 521*2c75bda4Serichkeane case OpenACCClauseKind::Collapse: 522*2c75bda4Serichkeane case OpenACCClauseKind::Gang: 523*2c75bda4Serichkeane case OpenACCClauseKind::Worker: 524*2c75bda4Serichkeane case OpenACCClauseKind::Vector: 525*2c75bda4Serichkeane case OpenACCClauseKind::Seq: 526*2c75bda4Serichkeane case OpenACCClauseKind::Independent: 527*2c75bda4Serichkeane case OpenACCClauseKind::Auto: 528*2c75bda4Serichkeane case OpenACCClauseKind::Tile: 529*2c75bda4Serichkeane return false; 530*2c75bda4Serichkeane default: 531*2c75bda4Serichkeane break; 532*2c75bda4Serichkeane } 533*2c75bda4Serichkeane } else if (isOpenACCCombinedDirectiveKind(NewClause.getDirectiveKind())) { 534*2c75bda4Serichkeane // This seems like it should be the union of 2.9 and 2.5.4 from above. 535*2c75bda4Serichkeane switch (NewClause.getClauseKind()) { 536*2c75bda4Serichkeane case OpenACCClauseKind::Async: 537*2c75bda4Serichkeane case OpenACCClauseKind::Wait: 538*2c75bda4Serichkeane case OpenACCClauseKind::NumGangs: 539*2c75bda4Serichkeane case OpenACCClauseKind::NumWorkers: 540*2c75bda4Serichkeane case OpenACCClauseKind::VectorLength: 541*2c75bda4Serichkeane case OpenACCClauseKind::Collapse: 542*2c75bda4Serichkeane case OpenACCClauseKind::Gang: 543*2c75bda4Serichkeane case OpenACCClauseKind::Worker: 544*2c75bda4Serichkeane case OpenACCClauseKind::Vector: 545*2c75bda4Serichkeane case OpenACCClauseKind::Seq: 546*2c75bda4Serichkeane case OpenACCClauseKind::Independent: 547*2c75bda4Serichkeane case OpenACCClauseKind::Auto: 548*2c75bda4Serichkeane case OpenACCClauseKind::Tile: 549*2c75bda4Serichkeane return false; 550*2c75bda4Serichkeane default: 551*2c75bda4Serichkeane break; 552*2c75bda4Serichkeane } 553*2c75bda4Serichkeane } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Data) { 554*2c75bda4Serichkeane // OpenACC3.3 section 2.6.5: Only the async and wait clauses may follow a 555*2c75bda4Serichkeane // device_type clause. 556*2c75bda4Serichkeane switch (NewClause.getClauseKind()) { 557*2c75bda4Serichkeane case OpenACCClauseKind::Async: 558*2c75bda4Serichkeane case OpenACCClauseKind::Wait: 559*2c75bda4Serichkeane return false; 560*2c75bda4Serichkeane default: 561*2c75bda4Serichkeane break; 562*2c75bda4Serichkeane } 563*2c75bda4Serichkeane } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Set || 564*2c75bda4Serichkeane NewClause.getDirectiveKind() == OpenACCDirectiveKind::Init || 565*2c75bda4Serichkeane NewClause.getDirectiveKind() == OpenACCDirectiveKind::Shutdown) { 566*2c75bda4Serichkeane // There are no restrictions on 'set', 'init', or 'shutdown'. 567*2c75bda4Serichkeane return false; 568*2c75bda4Serichkeane } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Update) { 569*2c75bda4Serichkeane // OpenACC3.3 section 2.14.4: Only the async and wait clauses may follow a 570*2c75bda4Serichkeane // device_type clause. 571*2c75bda4Serichkeane switch (NewClause.getClauseKind()) { 572*2c75bda4Serichkeane case OpenACCClauseKind::Async: 573*2c75bda4Serichkeane case OpenACCClauseKind::Wait: 574*2c75bda4Serichkeane return false; 575*2c75bda4Serichkeane default: 576*2c75bda4Serichkeane break; 577*2c75bda4Serichkeane } 578*2c75bda4Serichkeane } 579*2c75bda4Serichkeane S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type) 580*2c75bda4Serichkeane << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind() 581*2c75bda4Serichkeane << NewClause.getDirectiveKind(); 582*2c75bda4Serichkeane S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here); 583*2c75bda4Serichkeane return true; 584*2c75bda4Serichkeane } 585*2c75bda4Serichkeane 586*2c75bda4Serichkeane // A temporary function that helps implement the 'not implemented' check at the 587*2c75bda4Serichkeane // top of each clause checking function. This should only be used in conjunction 588*2c75bda4Serichkeane // with the one being currently implemented/only updated after the entire 589*2c75bda4Serichkeane // construct has been implemented. 590*2c75bda4Serichkeane bool isDirectiveKindImplemented(OpenACCDirectiveKind DK) { 591*2c75bda4Serichkeane return DK != OpenACCDirectiveKind::Declare && 592*2c75bda4Serichkeane DK != OpenACCDirectiveKind::Atomic && 593*2c75bda4Serichkeane DK != OpenACCDirectiveKind::Routine; 594*2c75bda4Serichkeane } 595*2c75bda4Serichkeane 596*2c75bda4Serichkeane class SemaOpenACCClauseVisitor { 597*2c75bda4Serichkeane SemaOpenACC &SemaRef; 598*2c75bda4Serichkeane ASTContext &Ctx; 599*2c75bda4Serichkeane ArrayRef<const OpenACCClause *> ExistingClauses; 600*2c75bda4Serichkeane bool NotImplemented = false; 601*2c75bda4Serichkeane 602*2c75bda4Serichkeane OpenACCClause *isNotImplemented() { 603*2c75bda4Serichkeane NotImplemented = true; 604*2c75bda4Serichkeane return nullptr; 605*2c75bda4Serichkeane } 606*2c75bda4Serichkeane 607*2c75bda4Serichkeane // OpenACC 3.3 2.9: 608*2c75bda4Serichkeane // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause 609*2c75bda4Serichkeane // appears. 610*2c75bda4Serichkeane bool DiagIfSeqClause(SemaOpenACC::OpenACCParsedClause &Clause) { 611*2c75bda4Serichkeane const auto *Itr = 612*2c75bda4Serichkeane llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>); 613*2c75bda4Serichkeane 614*2c75bda4Serichkeane if (Itr != ExistingClauses.end()) { 615*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine) 616*2c75bda4Serichkeane << Clause.getClauseKind() << (*Itr)->getClauseKind() 617*2c75bda4Serichkeane << Clause.getDirectiveKind(); 618*2c75bda4Serichkeane SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 619*2c75bda4Serichkeane 620*2c75bda4Serichkeane return true; 621*2c75bda4Serichkeane } 622*2c75bda4Serichkeane return false; 623*2c75bda4Serichkeane } 624*2c75bda4Serichkeane 625*2c75bda4Serichkeane public: 626*2c75bda4Serichkeane SemaOpenACCClauseVisitor(SemaOpenACC &S, 627*2c75bda4Serichkeane ArrayRef<const OpenACCClause *> ExistingClauses) 628*2c75bda4Serichkeane : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {} 629*2c75bda4Serichkeane // Once we've implemented everything, we shouldn't need this infrastructure. 630*2c75bda4Serichkeane // But in the meantime, we use this to help decide whether the clause was 631*2c75bda4Serichkeane // handled for this directive. 632*2c75bda4Serichkeane bool diagNotImplemented() { return NotImplemented; } 633*2c75bda4Serichkeane 634*2c75bda4Serichkeane OpenACCClause *Visit(SemaOpenACC::OpenACCParsedClause &Clause) { 635*2c75bda4Serichkeane switch (Clause.getClauseKind()) { 636*2c75bda4Serichkeane #define VISIT_CLAUSE(CLAUSE_NAME) \ 637*2c75bda4Serichkeane case OpenACCClauseKind::CLAUSE_NAME: \ 638*2c75bda4Serichkeane return Visit##CLAUSE_NAME##Clause(Clause); 639*2c75bda4Serichkeane #define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED) \ 640*2c75bda4Serichkeane case OpenACCClauseKind::ALIAS: \ 641*2c75bda4Serichkeane if (DEPRECATED) \ 642*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) \ 643*2c75bda4Serichkeane << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME; \ 644*2c75bda4Serichkeane return Visit##CLAUSE_NAME##Clause(Clause); 645*2c75bda4Serichkeane #include "clang/Basic/OpenACCClauses.def" 646*2c75bda4Serichkeane default: 647*2c75bda4Serichkeane return isNotImplemented(); 648*2c75bda4Serichkeane } 649*2c75bda4Serichkeane llvm_unreachable("Invalid clause kind"); 650*2c75bda4Serichkeane } 651*2c75bda4Serichkeane 652*2c75bda4Serichkeane #define VISIT_CLAUSE(CLAUSE_NAME) \ 653*2c75bda4Serichkeane OpenACCClause *Visit##CLAUSE_NAME##Clause( \ 654*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause); 655*2c75bda4Serichkeane #include "clang/Basic/OpenACCClauses.def" 656*2c75bda4Serichkeane }; 657*2c75bda4Serichkeane 658*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause( 659*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 660*2c75bda4Serichkeane // Don't add an invalid clause to the AST. 661*2c75bda4Serichkeane if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid) 662*2c75bda4Serichkeane return nullptr; 663*2c75bda4Serichkeane 664*2c75bda4Serichkeane // OpenACC 3.3, Section 2.5.4: 665*2c75bda4Serichkeane // At most one 'default' clause may appear, and it must have a value of 666*2c75bda4Serichkeane // either 'none' or 'present'. 667*2c75bda4Serichkeane // Second half of the sentence is diagnosed during parsing. 668*2c75bda4Serichkeane if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 669*2c75bda4Serichkeane return nullptr; 670*2c75bda4Serichkeane 671*2c75bda4Serichkeane return OpenACCDefaultClause::Create( 672*2c75bda4Serichkeane Ctx, Clause.getDefaultClauseKind(), Clause.getBeginLoc(), 673*2c75bda4Serichkeane Clause.getLParenLoc(), Clause.getEndLoc()); 674*2c75bda4Serichkeane } 675*2c75bda4Serichkeane 676*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause( 677*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 678*2c75bda4Serichkeane 679*2c75bda4Serichkeane // Duplicates here are not really sensible. We could possible permit 680*2c75bda4Serichkeane // multiples if they all had the same value, but there isn't really a good 681*2c75bda4Serichkeane // reason to do so. Also, this simplifies the suppression of duplicates, in 682*2c75bda4Serichkeane // that we know if we 'find' one after instantiation, that it is the same 683*2c75bda4Serichkeane // clause, which simplifies instantiation/checking/etc. 684*2c75bda4Serichkeane if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 685*2c75bda4Serichkeane return nullptr; 686*2c75bda4Serichkeane 687*2c75bda4Serichkeane llvm::SmallVector<Expr *> NewSizeExprs; 688*2c75bda4Serichkeane 689*2c75bda4Serichkeane // Make sure these are all positive constant expressions or *. 690*2c75bda4Serichkeane for (Expr *E : Clause.getIntExprs()) { 691*2c75bda4Serichkeane ExprResult Res = SemaRef.CheckTileSizeExpr(E); 692*2c75bda4Serichkeane 693*2c75bda4Serichkeane if (!Res.isUsable()) 694*2c75bda4Serichkeane return nullptr; 695*2c75bda4Serichkeane 696*2c75bda4Serichkeane NewSizeExprs.push_back(Res.get()); 697*2c75bda4Serichkeane } 698*2c75bda4Serichkeane 699*2c75bda4Serichkeane return OpenACCTileClause::Create(Ctx, Clause.getBeginLoc(), 700*2c75bda4Serichkeane Clause.getLParenLoc(), NewSizeExprs, 701*2c75bda4Serichkeane Clause.getEndLoc()); 702*2c75bda4Serichkeane } 703*2c75bda4Serichkeane 704*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause( 705*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 706*2c75bda4Serichkeane // There is no prose in the standard that says duplicates aren't allowed, 707*2c75bda4Serichkeane // but this diagnostic is present in other compilers, as well as makes 708*2c75bda4Serichkeane // sense. Prose DOES exist for 'data' and 'host_data', 'set', 'enter data' and 709*2c75bda4Serichkeane // 'exit data' both don't, but other implmementations do this. OpenACC issue 710*2c75bda4Serichkeane // 519 filed for the latter two. Prose also exists for 'update'. 711*2c75bda4Serichkeane // GCC allows this on init/shutdown, presumably for good reason, so we do too. 712*2c75bda4Serichkeane if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Init && 713*2c75bda4Serichkeane Clause.getDirectiveKind() != OpenACCDirectiveKind::Shutdown && 714*2c75bda4Serichkeane checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 715*2c75bda4Serichkeane return nullptr; 716*2c75bda4Serichkeane 717*2c75bda4Serichkeane // The parser has ensured that we have a proper condition expr, so there 718*2c75bda4Serichkeane // isn't really much to do here. 719*2c75bda4Serichkeane 720*2c75bda4Serichkeane // If the 'if' clause is true, it makes the 'self' clause have no effect, 721*2c75bda4Serichkeane // diagnose that here. This only applies on compute/combined constructs. 722*2c75bda4Serichkeane if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Update) { 723*2c75bda4Serichkeane const auto *Itr = 724*2c75bda4Serichkeane llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>); 725*2c75bda4Serichkeane if (Itr != ExistingClauses.end()) { 726*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict); 727*2c75bda4Serichkeane SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 728*2c75bda4Serichkeane } 729*2c75bda4Serichkeane } 730*2c75bda4Serichkeane 731*2c75bda4Serichkeane return OpenACCIfClause::Create(Ctx, Clause.getBeginLoc(), 732*2c75bda4Serichkeane Clause.getLParenLoc(), 733*2c75bda4Serichkeane Clause.getConditionExpr(), Clause.getEndLoc()); 734*2c75bda4Serichkeane } 735*2c75bda4Serichkeane 736*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause( 737*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 738*2c75bda4Serichkeane // There is no prose in the standard that says duplicates aren't allowed, 739*2c75bda4Serichkeane // but this diagnostic is present in other compilers, as well as makes 740*2c75bda4Serichkeane // sense. 741*2c75bda4Serichkeane if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 742*2c75bda4Serichkeane return nullptr; 743*2c75bda4Serichkeane 744*2c75bda4Serichkeane // If the 'if' clause is true, it makes the 'self' clause have no effect, 745*2c75bda4Serichkeane // diagnose that here. This only applies on compute/combined constructs. 746*2c75bda4Serichkeane if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Update) 747*2c75bda4Serichkeane return OpenACCSelfClause::Create(Ctx, Clause.getBeginLoc(), 748*2c75bda4Serichkeane Clause.getLParenLoc(), Clause.getVarList(), 749*2c75bda4Serichkeane Clause.getEndLoc()); 750*2c75bda4Serichkeane 751*2c75bda4Serichkeane const auto *Itr = 752*2c75bda4Serichkeane llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>); 753*2c75bda4Serichkeane if (Itr != ExistingClauses.end()) { 754*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict); 755*2c75bda4Serichkeane SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 756*2c75bda4Serichkeane } 757*2c75bda4Serichkeane return OpenACCSelfClause::Create( 758*2c75bda4Serichkeane Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), 759*2c75bda4Serichkeane Clause.getConditionExpr(), Clause.getEndLoc()); 760*2c75bda4Serichkeane } 761*2c75bda4Serichkeane 762*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause( 763*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 764*2c75bda4Serichkeane // There is no prose in the standard that says duplicates aren't allowed, 765*2c75bda4Serichkeane // but this diagnostic is present in other compilers, as well as makes 766*2c75bda4Serichkeane // sense. 767*2c75bda4Serichkeane if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 768*2c75bda4Serichkeane return nullptr; 769*2c75bda4Serichkeane 770*2c75bda4Serichkeane // num_gangs requires at least 1 int expr in all forms. Diagnose here, but 771*2c75bda4Serichkeane // allow us to continue, an empty clause might be useful for future 772*2c75bda4Serichkeane // diagnostics. 773*2c75bda4Serichkeane if (Clause.getIntExprs().empty()) 774*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) 775*2c75bda4Serichkeane << /*NoArgs=*/0; 776*2c75bda4Serichkeane 777*2c75bda4Serichkeane unsigned MaxArgs = 778*2c75bda4Serichkeane (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || 779*2c75bda4Serichkeane Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) 780*2c75bda4Serichkeane ? 3 781*2c75bda4Serichkeane : 1; 782*2c75bda4Serichkeane // The max number of args differs between parallel and other constructs. 783*2c75bda4Serichkeane // Again, allow us to continue for the purposes of future diagnostics. 784*2c75bda4Serichkeane if (Clause.getIntExprs().size() > MaxArgs) 785*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) 786*2c75bda4Serichkeane << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs 787*2c75bda4Serichkeane << Clause.getIntExprs().size(); 788*2c75bda4Serichkeane 789*2c75bda4Serichkeane // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop 790*2c75bda4Serichkeane // directive that has a gang clause and is within a compute construct that has 791*2c75bda4Serichkeane // a num_gangs clause with more than one explicit argument. 792*2c75bda4Serichkeane if (Clause.getIntExprs().size() > 1 && 793*2c75bda4Serichkeane isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 794*2c75bda4Serichkeane auto *GangClauseItr = 795*2c75bda4Serichkeane llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>); 796*2c75bda4Serichkeane auto *ReductionClauseItr = 797*2c75bda4Serichkeane llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>); 798*2c75bda4Serichkeane 799*2c75bda4Serichkeane if (GangClauseItr != ExistingClauses.end() && 800*2c75bda4Serichkeane ReductionClauseItr != ExistingClauses.end()) { 801*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), 802*2c75bda4Serichkeane diag::err_acc_gang_reduction_numgangs_conflict) 803*2c75bda4Serichkeane << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang 804*2c75bda4Serichkeane << Clause.getDirectiveKind() << /*is on combined directive=*/1; 805*2c75bda4Serichkeane SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(), 806*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 807*2c75bda4Serichkeane SemaRef.Diag((*GangClauseItr)->getBeginLoc(), 808*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 809*2c75bda4Serichkeane return nullptr; 810*2c75bda4Serichkeane } 811*2c75bda4Serichkeane } 812*2c75bda4Serichkeane 813*2c75bda4Serichkeane // OpenACC 3.3 Section 2.5.4: 814*2c75bda4Serichkeane // A reduction clause may not appear on a parallel construct with a 815*2c75bda4Serichkeane // num_gangs clause that has more than one argument. 816*2c75bda4Serichkeane if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || 817*2c75bda4Serichkeane Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) && 818*2c75bda4Serichkeane Clause.getIntExprs().size() > 1) { 819*2c75bda4Serichkeane auto *Parallel = 820*2c75bda4Serichkeane llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>); 821*2c75bda4Serichkeane 822*2c75bda4Serichkeane if (Parallel != ExistingClauses.end()) { 823*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), 824*2c75bda4Serichkeane diag::err_acc_reduction_num_gangs_conflict) 825*2c75bda4Serichkeane << /*>1 arg in first loc=*/1 << Clause.getClauseKind() 826*2c75bda4Serichkeane << Clause.getDirectiveKind() << OpenACCClauseKind::Reduction; 827*2c75bda4Serichkeane SemaRef.Diag((*Parallel)->getBeginLoc(), 828*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 829*2c75bda4Serichkeane return nullptr; 830*2c75bda4Serichkeane } 831*2c75bda4Serichkeane } 832*2c75bda4Serichkeane 833*2c75bda4Serichkeane // OpenACC 3.3 Section 2.9.2: 834*2c75bda4Serichkeane // An argument with no keyword or with the 'num' keyword is allowed only when 835*2c75bda4Serichkeane // the 'num_gangs' does not appear on the 'kernel' construct. 836*2c75bda4Serichkeane if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) { 837*2c75bda4Serichkeane auto GangClauses = llvm::make_filter_range( 838*2c75bda4Serichkeane ExistingClauses, llvm::IsaPred<OpenACCGangClause>); 839*2c75bda4Serichkeane 840*2c75bda4Serichkeane for (auto *GC : GangClauses) { 841*2c75bda4Serichkeane if (cast<OpenACCGangClause>(GC)->hasExprOfKind(OpenACCGangKind::Num)) { 842*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), 843*2c75bda4Serichkeane diag::err_acc_num_arg_conflict_reverse) 844*2c75bda4Serichkeane << OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang 845*2c75bda4Serichkeane << /*Num argument*/ 1; 846*2c75bda4Serichkeane SemaRef.Diag(GC->getBeginLoc(), diag::note_acc_previous_clause_here); 847*2c75bda4Serichkeane return nullptr; 848*2c75bda4Serichkeane } 849*2c75bda4Serichkeane } 850*2c75bda4Serichkeane } 851*2c75bda4Serichkeane 852*2c75bda4Serichkeane return OpenACCNumGangsClause::Create( 853*2c75bda4Serichkeane Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs(), 854*2c75bda4Serichkeane Clause.getEndLoc()); 855*2c75bda4Serichkeane } 856*2c75bda4Serichkeane 857*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause( 858*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 859*2c75bda4Serichkeane // There is no prose in the standard that says duplicates aren't allowed, 860*2c75bda4Serichkeane // but this diagnostic is present in other compilers, as well as makes 861*2c75bda4Serichkeane // sense. 862*2c75bda4Serichkeane if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 863*2c75bda4Serichkeane return nullptr; 864*2c75bda4Serichkeane 865*2c75bda4Serichkeane // OpenACC 3.3 Section 2.9.2: 866*2c75bda4Serichkeane // An argument is allowed only when the 'num_workers' does not appear on the 867*2c75bda4Serichkeane // kernels construct. 868*2c75bda4Serichkeane if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) { 869*2c75bda4Serichkeane auto WorkerClauses = llvm::make_filter_range( 870*2c75bda4Serichkeane ExistingClauses, llvm::IsaPred<OpenACCWorkerClause>); 871*2c75bda4Serichkeane 872*2c75bda4Serichkeane for (auto *WC : WorkerClauses) { 873*2c75bda4Serichkeane if (cast<OpenACCWorkerClause>(WC)->hasIntExpr()) { 874*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), 875*2c75bda4Serichkeane diag::err_acc_num_arg_conflict_reverse) 876*2c75bda4Serichkeane << OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker 877*2c75bda4Serichkeane << /*num argument*/ 0; 878*2c75bda4Serichkeane SemaRef.Diag(WC->getBeginLoc(), diag::note_acc_previous_clause_here); 879*2c75bda4Serichkeane return nullptr; 880*2c75bda4Serichkeane } 881*2c75bda4Serichkeane } 882*2c75bda4Serichkeane } 883*2c75bda4Serichkeane 884*2c75bda4Serichkeane assert(Clause.getIntExprs().size() == 1 && 885*2c75bda4Serichkeane "Invalid number of expressions for NumWorkers"); 886*2c75bda4Serichkeane return OpenACCNumWorkersClause::Create( 887*2c75bda4Serichkeane Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], 888*2c75bda4Serichkeane Clause.getEndLoc()); 889*2c75bda4Serichkeane } 890*2c75bda4Serichkeane 891*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause( 892*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 893*2c75bda4Serichkeane // There is no prose in the standard that says duplicates aren't allowed, 894*2c75bda4Serichkeane // but this diagnostic is present in other compilers, as well as makes 895*2c75bda4Serichkeane // sense. 896*2c75bda4Serichkeane if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 897*2c75bda4Serichkeane return nullptr; 898*2c75bda4Serichkeane 899*2c75bda4Serichkeane // OpenACC 3.3 Section 2.9.4: 900*2c75bda4Serichkeane // An argument is allowed only when the 'vector_length' does not appear on the 901*2c75bda4Serichkeane // 'kernels' construct. 902*2c75bda4Serichkeane if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) { 903*2c75bda4Serichkeane auto VectorClauses = llvm::make_filter_range( 904*2c75bda4Serichkeane ExistingClauses, llvm::IsaPred<OpenACCVectorClause>); 905*2c75bda4Serichkeane 906*2c75bda4Serichkeane for (auto *VC : VectorClauses) { 907*2c75bda4Serichkeane if (cast<OpenACCVectorClause>(VC)->hasIntExpr()) { 908*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), 909*2c75bda4Serichkeane diag::err_acc_num_arg_conflict_reverse) 910*2c75bda4Serichkeane << OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector 911*2c75bda4Serichkeane << /*num argument*/ 0; 912*2c75bda4Serichkeane SemaRef.Diag(VC->getBeginLoc(), diag::note_acc_previous_clause_here); 913*2c75bda4Serichkeane return nullptr; 914*2c75bda4Serichkeane } 915*2c75bda4Serichkeane } 916*2c75bda4Serichkeane } 917*2c75bda4Serichkeane 918*2c75bda4Serichkeane assert(Clause.getIntExprs().size() == 1 && 919*2c75bda4Serichkeane "Invalid number of expressions for NumWorkers"); 920*2c75bda4Serichkeane return OpenACCVectorLengthClause::Create( 921*2c75bda4Serichkeane Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], 922*2c75bda4Serichkeane Clause.getEndLoc()); 923*2c75bda4Serichkeane } 924*2c75bda4Serichkeane 925*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause( 926*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 927*2c75bda4Serichkeane // There is no prose in the standard that says duplicates aren't allowed, 928*2c75bda4Serichkeane // but this diagnostic is present in other compilers, as well as makes 929*2c75bda4Serichkeane // sense. 930*2c75bda4Serichkeane if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 931*2c75bda4Serichkeane return nullptr; 932*2c75bda4Serichkeane 933*2c75bda4Serichkeane assert(Clause.getNumIntExprs() < 2 && 934*2c75bda4Serichkeane "Invalid number of expressions for Async"); 935*2c75bda4Serichkeane return OpenACCAsyncClause::Create( 936*2c75bda4Serichkeane Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), 937*2c75bda4Serichkeane Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr, 938*2c75bda4Serichkeane Clause.getEndLoc()); 939*2c75bda4Serichkeane } 940*2c75bda4Serichkeane 941*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceNumClause( 942*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 943*2c75bda4Serichkeane // Restrictions only properly implemented on certain constructs, so skip/treat 944*2c75bda4Serichkeane // as unimplemented in those cases. 945*2c75bda4Serichkeane if (!isDirectiveKindImplemented(Clause.getDirectiveKind())) 946*2c75bda4Serichkeane return isNotImplemented(); 947*2c75bda4Serichkeane 948*2c75bda4Serichkeane // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the 949*2c75bda4Serichkeane // same directive. 950*2c75bda4Serichkeane if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set && 951*2c75bda4Serichkeane checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 952*2c75bda4Serichkeane return nullptr; 953*2c75bda4Serichkeane 954*2c75bda4Serichkeane assert(Clause.getNumIntExprs() == 1 && 955*2c75bda4Serichkeane "Invalid number of expressions for device_num"); 956*2c75bda4Serichkeane return OpenACCDeviceNumClause::Create( 957*2c75bda4Serichkeane Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], 958*2c75bda4Serichkeane Clause.getEndLoc()); 959*2c75bda4Serichkeane } 960*2c75bda4Serichkeane 961*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultAsyncClause( 962*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 963*2c75bda4Serichkeane // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the 964*2c75bda4Serichkeane // same directive. 965*2c75bda4Serichkeane if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 966*2c75bda4Serichkeane return nullptr; 967*2c75bda4Serichkeane 968*2c75bda4Serichkeane assert(Clause.getNumIntExprs() == 1 && 969*2c75bda4Serichkeane "Invalid number of expressions for default_async"); 970*2c75bda4Serichkeane return OpenACCDefaultAsyncClause::Create( 971*2c75bda4Serichkeane Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], 972*2c75bda4Serichkeane Clause.getEndLoc()); 973*2c75bda4Serichkeane } 974*2c75bda4Serichkeane 975*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause( 976*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 977*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, so there 978*2c75bda4Serichkeane // really isn't anything to do here. GCC does some duplicate-finding, though 979*2c75bda4Serichkeane // it isn't apparent in the standard where this is justified. 980*2c75bda4Serichkeane 981*2c75bda4Serichkeane return OpenACCPrivateClause::Create(Ctx, Clause.getBeginLoc(), 982*2c75bda4Serichkeane Clause.getLParenLoc(), 983*2c75bda4Serichkeane Clause.getVarList(), Clause.getEndLoc()); 984*2c75bda4Serichkeane } 985*2c75bda4Serichkeane 986*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause( 987*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 988*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, so there 989*2c75bda4Serichkeane // really isn't anything to do here. GCC does some duplicate-finding, though 990*2c75bda4Serichkeane // it isn't apparent in the standard where this is justified. 991*2c75bda4Serichkeane 992*2c75bda4Serichkeane return OpenACCFirstPrivateClause::Create( 993*2c75bda4Serichkeane Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), 994*2c75bda4Serichkeane Clause.getEndLoc()); 995*2c75bda4Serichkeane } 996*2c75bda4Serichkeane 997*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause( 998*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 999*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, so there 1000*2c75bda4Serichkeane // really isn't anything to do here. GCC does some duplicate-finding, though 1001*2c75bda4Serichkeane // it isn't apparent in the standard where this is justified. 1002*2c75bda4Serichkeane 1003*2c75bda4Serichkeane return OpenACCNoCreateClause::Create(Ctx, Clause.getBeginLoc(), 1004*2c75bda4Serichkeane Clause.getLParenLoc(), 1005*2c75bda4Serichkeane Clause.getVarList(), Clause.getEndLoc()); 1006*2c75bda4Serichkeane } 1007*2c75bda4Serichkeane 1008*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause( 1009*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1010*2c75bda4Serichkeane // Restrictions only properly implemented on 'compute'/'combined'/'data' 1011*2c75bda4Serichkeane // constructs, and 'compute'/'combined'/'data' constructs are the only 1012*2c75bda4Serichkeane // construct that can do anything with this yet, so skip/treat as 1013*2c75bda4Serichkeane // unimplemented in this case. 1014*2c75bda4Serichkeane if (!isDirectiveKindImplemented(Clause.getDirectiveKind())) 1015*2c75bda4Serichkeane return isNotImplemented(); 1016*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, so there 1017*2c75bda4Serichkeane // really isn't anything to do here. GCC does some duplicate-finding, though 1018*2c75bda4Serichkeane // it isn't apparent in the standard where this is justified. 1019*2c75bda4Serichkeane 1020*2c75bda4Serichkeane return OpenACCPresentClause::Create(Ctx, Clause.getBeginLoc(), 1021*2c75bda4Serichkeane Clause.getLParenLoc(), 1022*2c75bda4Serichkeane Clause.getVarList(), Clause.getEndLoc()); 1023*2c75bda4Serichkeane } 1024*2c75bda4Serichkeane 1025*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitHostClause( 1026*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1027*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, so there 1028*2c75bda4Serichkeane // really isn't anything to do here. GCC does some duplicate-finding, though 1029*2c75bda4Serichkeane // it isn't apparent in the standard where this is justified. 1030*2c75bda4Serichkeane 1031*2c75bda4Serichkeane return OpenACCHostClause::Create(Ctx, Clause.getBeginLoc(), 1032*2c75bda4Serichkeane Clause.getLParenLoc(), Clause.getVarList(), 1033*2c75bda4Serichkeane Clause.getEndLoc()); 1034*2c75bda4Serichkeane } 1035*2c75bda4Serichkeane 1036*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceClause( 1037*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1038*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, so there 1039*2c75bda4Serichkeane // really isn't anything to do here. GCC does some duplicate-finding, though 1040*2c75bda4Serichkeane // it isn't apparent in the standard where this is justified. 1041*2c75bda4Serichkeane 1042*2c75bda4Serichkeane return OpenACCDeviceClause::Create(Ctx, Clause.getBeginLoc(), 1043*2c75bda4Serichkeane Clause.getLParenLoc(), Clause.getVarList(), 1044*2c75bda4Serichkeane Clause.getEndLoc()); 1045*2c75bda4Serichkeane } 1046*2c75bda4Serichkeane 1047*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause( 1048*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1049*2c75bda4Serichkeane // Restrictions only properly implemented on 'compute'/'combined'/'data' 1050*2c75bda4Serichkeane // constructs, and 'compute'/'combined'/'data' constructs are the only 1051*2c75bda4Serichkeane // construct that can do anything with this yet, so skip/treat as 1052*2c75bda4Serichkeane // unimplemented in this case. 1053*2c75bda4Serichkeane if (!isDirectiveKindImplemented(Clause.getDirectiveKind())) 1054*2c75bda4Serichkeane return isNotImplemented(); 1055*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, so there 1056*2c75bda4Serichkeane // really isn't anything to do here. GCC does some duplicate-finding, though 1057*2c75bda4Serichkeane // it isn't apparent in the standard where this is justified. 1058*2c75bda4Serichkeane 1059*2c75bda4Serichkeane return OpenACCCopyClause::Create( 1060*2c75bda4Serichkeane Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 1061*2c75bda4Serichkeane Clause.getVarList(), Clause.getEndLoc()); 1062*2c75bda4Serichkeane } 1063*2c75bda4Serichkeane 1064*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause( 1065*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1066*2c75bda4Serichkeane // Restrictions only properly implemented on 'compute'/'combined'/'data' 1067*2c75bda4Serichkeane // constructs, and 'compute'/'combined'/'data' constructs are the only 1068*2c75bda4Serichkeane // construct that can do anything with this yet, so skip/treat as 1069*2c75bda4Serichkeane // unimplemented in this case. 1070*2c75bda4Serichkeane if (!isDirectiveKindImplemented(Clause.getDirectiveKind())) 1071*2c75bda4Serichkeane return isNotImplemented(); 1072*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, so there 1073*2c75bda4Serichkeane // really isn't anything to do here. GCC does some duplicate-finding, though 1074*2c75bda4Serichkeane // it isn't apparent in the standard where this is justified. 1075*2c75bda4Serichkeane 1076*2c75bda4Serichkeane return OpenACCCopyInClause::Create( 1077*2c75bda4Serichkeane Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 1078*2c75bda4Serichkeane Clause.isReadOnly(), Clause.getVarList(), Clause.getEndLoc()); 1079*2c75bda4Serichkeane } 1080*2c75bda4Serichkeane 1081*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause( 1082*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1083*2c75bda4Serichkeane // Restrictions only properly implemented on 'compute'/'combined'/'data' 1084*2c75bda4Serichkeane // constructs, and 'compute'/'combined'/'data' constructs are the only 1085*2c75bda4Serichkeane // construct that can do anything with this yet, so skip/treat as 1086*2c75bda4Serichkeane // unimplemented in this case. 1087*2c75bda4Serichkeane if (!isDirectiveKindImplemented(Clause.getDirectiveKind())) 1088*2c75bda4Serichkeane return isNotImplemented(); 1089*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, so there 1090*2c75bda4Serichkeane // really isn't anything to do here. GCC does some duplicate-finding, though 1091*2c75bda4Serichkeane // it isn't apparent in the standard where this is justified. 1092*2c75bda4Serichkeane 1093*2c75bda4Serichkeane return OpenACCCopyOutClause::Create( 1094*2c75bda4Serichkeane Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 1095*2c75bda4Serichkeane Clause.isZero(), Clause.getVarList(), Clause.getEndLoc()); 1096*2c75bda4Serichkeane } 1097*2c75bda4Serichkeane 1098*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause( 1099*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1100*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, so there 1101*2c75bda4Serichkeane // really isn't anything to do here. GCC does some duplicate-finding, though 1102*2c75bda4Serichkeane // it isn't apparent in the standard where this is justified. 1103*2c75bda4Serichkeane 1104*2c75bda4Serichkeane return OpenACCCreateClause::Create( 1105*2c75bda4Serichkeane Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 1106*2c75bda4Serichkeane Clause.isZero(), Clause.getVarList(), Clause.getEndLoc()); 1107*2c75bda4Serichkeane } 1108*2c75bda4Serichkeane 1109*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause( 1110*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1111*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, but we 1112*2c75bda4Serichkeane // still have to make sure it is a pointer type. 1113*2c75bda4Serichkeane llvm::SmallVector<Expr *> VarList{Clause.getVarList()}; 1114*2c75bda4Serichkeane llvm::erase_if(VarList, [&](Expr *E) { 1115*2c75bda4Serichkeane return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Attach, E); 1116*2c75bda4Serichkeane }); 1117*2c75bda4Serichkeane Clause.setVarListDetails(VarList, 1118*2c75bda4Serichkeane /*IsReadOnly=*/false, /*IsZero=*/false); 1119*2c75bda4Serichkeane return OpenACCAttachClause::Create(Ctx, Clause.getBeginLoc(), 1120*2c75bda4Serichkeane Clause.getLParenLoc(), Clause.getVarList(), 1121*2c75bda4Serichkeane Clause.getEndLoc()); 1122*2c75bda4Serichkeane } 1123*2c75bda4Serichkeane 1124*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause( 1125*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1126*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, but we 1127*2c75bda4Serichkeane // still have to make sure it is a pointer type. 1128*2c75bda4Serichkeane llvm::SmallVector<Expr *> VarList{Clause.getVarList()}; 1129*2c75bda4Serichkeane llvm::erase_if(VarList, [&](Expr *E) { 1130*2c75bda4Serichkeane return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Detach, E); 1131*2c75bda4Serichkeane }); 1132*2c75bda4Serichkeane Clause.setVarListDetails(VarList, 1133*2c75bda4Serichkeane /*IsReadOnly=*/false, /*IsZero=*/false); 1134*2c75bda4Serichkeane return OpenACCDetachClause::Create(Ctx, Clause.getBeginLoc(), 1135*2c75bda4Serichkeane Clause.getLParenLoc(), Clause.getVarList(), 1136*2c75bda4Serichkeane Clause.getEndLoc()); 1137*2c75bda4Serichkeane } 1138*2c75bda4Serichkeane 1139*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause( 1140*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1141*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, so there 1142*2c75bda4Serichkeane // really isn't anything to do here. GCC does some duplicate-finding, though 1143*2c75bda4Serichkeane // it isn't apparent in the standard where this is justified. 1144*2c75bda4Serichkeane return OpenACCDeleteClause::Create(Ctx, Clause.getBeginLoc(), 1145*2c75bda4Serichkeane Clause.getLParenLoc(), Clause.getVarList(), 1146*2c75bda4Serichkeane Clause.getEndLoc()); 1147*2c75bda4Serichkeane } 1148*2c75bda4Serichkeane 1149*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitUseDeviceClause( 1150*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1151*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable or array, so nothing 1152*2c75bda4Serichkeane // left to do here. 1153*2c75bda4Serichkeane return OpenACCUseDeviceClause::Create( 1154*2c75bda4Serichkeane Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), 1155*2c75bda4Serichkeane Clause.getEndLoc()); 1156*2c75bda4Serichkeane } 1157*2c75bda4Serichkeane 1158*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause( 1159*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1160*2c75bda4Serichkeane // Restrictions only properly implemented on 'compute'/'combined'/'data' 1161*2c75bda4Serichkeane // constructs, and 'compute'/'combined'/'data' constructs are the only 1162*2c75bda4Serichkeane // construct that can do anything with this yet, so skip/treat as 1163*2c75bda4Serichkeane // unimplemented in this case. 1164*2c75bda4Serichkeane if (!isDirectiveKindImplemented(Clause.getDirectiveKind())) 1165*2c75bda4Serichkeane return isNotImplemented(); 1166*2c75bda4Serichkeane 1167*2c75bda4Serichkeane // ActOnVar ensured that everything is a valid variable reference, but we 1168*2c75bda4Serichkeane // still have to make sure it is a pointer type. 1169*2c75bda4Serichkeane llvm::SmallVector<Expr *> VarList{Clause.getVarList()}; 1170*2c75bda4Serichkeane llvm::erase_if(VarList, [&](Expr *E) { 1171*2c75bda4Serichkeane return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::DevicePtr, E); 1172*2c75bda4Serichkeane }); 1173*2c75bda4Serichkeane Clause.setVarListDetails(VarList, 1174*2c75bda4Serichkeane /*IsReadOnly=*/false, /*IsZero=*/false); 1175*2c75bda4Serichkeane 1176*2c75bda4Serichkeane return OpenACCDevicePtrClause::Create( 1177*2c75bda4Serichkeane Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), 1178*2c75bda4Serichkeane Clause.getEndLoc()); 1179*2c75bda4Serichkeane } 1180*2c75bda4Serichkeane 1181*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause( 1182*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1183*2c75bda4Serichkeane return OpenACCWaitClause::Create( 1184*2c75bda4Serichkeane Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getDevNumExpr(), 1185*2c75bda4Serichkeane Clause.getQueuesLoc(), Clause.getQueueIdExprs(), Clause.getEndLoc()); 1186*2c75bda4Serichkeane } 1187*2c75bda4Serichkeane 1188*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause( 1189*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1190*2c75bda4Serichkeane // Restrictions implemented properly on everything except 'routine'. 1191*2c75bda4Serichkeane if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Routine) 1192*2c75bda4Serichkeane return isNotImplemented(); 1193*2c75bda4Serichkeane 1194*2c75bda4Serichkeane // OpenACC 3.3 2.14.3: Two instances of the same clause may not appear on the 1195*2c75bda4Serichkeane // same directive. 1196*2c75bda4Serichkeane if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Set && 1197*2c75bda4Serichkeane checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 1198*2c75bda4Serichkeane return nullptr; 1199*2c75bda4Serichkeane 1200*2c75bda4Serichkeane // TODO OpenACC: Once we get enough of the CodeGen implemented that we have 1201*2c75bda4Serichkeane // a source for the list of valid architectures, we need to warn on unknown 1202*2c75bda4Serichkeane // identifiers here. 1203*2c75bda4Serichkeane 1204*2c75bda4Serichkeane return OpenACCDeviceTypeClause::Create( 1205*2c75bda4Serichkeane Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 1206*2c75bda4Serichkeane Clause.getDeviceTypeArchitectures(), Clause.getEndLoc()); 1207*2c75bda4Serichkeane } 1208*2c75bda4Serichkeane 1209*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause( 1210*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1211*2c75bda4Serichkeane // OpenACC 3.3 2.9: 1212*2c75bda4Serichkeane // Only one of the seq, independent, and auto clauses may appear. 1213*2c75bda4Serichkeane const auto *Itr = 1214*2c75bda4Serichkeane llvm::find_if(ExistingClauses, 1215*2c75bda4Serichkeane llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>); 1216*2c75bda4Serichkeane if (Itr != ExistingClauses.end()) { 1217*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict) 1218*2c75bda4Serichkeane << Clause.getClauseKind() << Clause.getDirectiveKind(); 1219*2c75bda4Serichkeane SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 1220*2c75bda4Serichkeane return nullptr; 1221*2c75bda4Serichkeane } 1222*2c75bda4Serichkeane 1223*2c75bda4Serichkeane return OpenACCAutoClause::Create(Ctx, Clause.getBeginLoc(), 1224*2c75bda4Serichkeane Clause.getEndLoc()); 1225*2c75bda4Serichkeane } 1226*2c75bda4Serichkeane 1227*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause( 1228*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1229*2c75bda4Serichkeane // OpenACC 3.3 2.9: 1230*2c75bda4Serichkeane // Only one of the seq, independent, and auto clauses may appear. 1231*2c75bda4Serichkeane const auto *Itr = llvm::find_if( 1232*2c75bda4Serichkeane ExistingClauses, llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>); 1233*2c75bda4Serichkeane if (Itr != ExistingClauses.end()) { 1234*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict) 1235*2c75bda4Serichkeane << Clause.getClauseKind() << Clause.getDirectiveKind(); 1236*2c75bda4Serichkeane SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 1237*2c75bda4Serichkeane return nullptr; 1238*2c75bda4Serichkeane } 1239*2c75bda4Serichkeane 1240*2c75bda4Serichkeane return OpenACCIndependentClause::Create(Ctx, Clause.getBeginLoc(), 1241*2c75bda4Serichkeane Clause.getEndLoc()); 1242*2c75bda4Serichkeane } 1243*2c75bda4Serichkeane 1244*2c75bda4Serichkeane ExprResult CheckGangStaticExpr(SemaOpenACC &S, Expr *E) { 1245*2c75bda4Serichkeane if (isa<OpenACCAsteriskSizeExpr>(E)) 1246*2c75bda4Serichkeane return E; 1247*2c75bda4Serichkeane return S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang, 1248*2c75bda4Serichkeane E->getBeginLoc(), E); 1249*2c75bda4Serichkeane } 1250*2c75bda4Serichkeane 1251*2c75bda4Serichkeane bool IsOrphanLoop(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) { 1252*2c75bda4Serichkeane return DK == OpenACCDirectiveKind::Loop && 1253*2c75bda4Serichkeane AssocKind == OpenACCDirectiveKind::Invalid; 1254*2c75bda4Serichkeane } 1255*2c75bda4Serichkeane 1256*2c75bda4Serichkeane bool HasAssocKind(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) { 1257*2c75bda4Serichkeane return DK == OpenACCDirectiveKind::Loop && 1258*2c75bda4Serichkeane AssocKind != OpenACCDirectiveKind::Invalid; 1259*2c75bda4Serichkeane } 1260*2c75bda4Serichkeane 1261*2c75bda4Serichkeane ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, OpenACCGangKind GK, 1262*2c75bda4Serichkeane OpenACCClauseKind CK, OpenACCDirectiveKind DK, 1263*2c75bda4Serichkeane OpenACCDirectiveKind AssocKind) { 1264*2c75bda4Serichkeane S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid) 1265*2c75bda4Serichkeane << GK << CK << IsOrphanLoop(DK, AssocKind) << DK 1266*2c75bda4Serichkeane << HasAssocKind(DK, AssocKind) << AssocKind; 1267*2c75bda4Serichkeane return ExprError(); 1268*2c75bda4Serichkeane } 1269*2c75bda4Serichkeane ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, StringRef TagKind, 1270*2c75bda4Serichkeane OpenACCClauseKind CK, OpenACCDirectiveKind DK, 1271*2c75bda4Serichkeane OpenACCDirectiveKind AssocKind) { 1272*2c75bda4Serichkeane S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid) 1273*2c75bda4Serichkeane << TagKind << CK << IsOrphanLoop(DK, AssocKind) << DK 1274*2c75bda4Serichkeane << HasAssocKind(DK, AssocKind) << AssocKind; 1275*2c75bda4Serichkeane return ExprError(); 1276*2c75bda4Serichkeane } 1277*2c75bda4Serichkeane 1278*2c75bda4Serichkeane ExprResult CheckGangParallelExpr(SemaOpenACC &S, OpenACCDirectiveKind DK, 1279*2c75bda4Serichkeane OpenACCDirectiveKind AssocKind, 1280*2c75bda4Serichkeane OpenACCGangKind GK, Expr *E) { 1281*2c75bda4Serichkeane switch (GK) { 1282*2c75bda4Serichkeane case OpenACCGangKind::Static: 1283*2c75bda4Serichkeane return CheckGangStaticExpr(S, E); 1284*2c75bda4Serichkeane case OpenACCGangKind::Num: 1285*2c75bda4Serichkeane // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel 1286*2c75bda4Serichkeane // construct, or an orphaned loop construct, the gang clause behaves as 1287*2c75bda4Serichkeane // follows. ... The num argument is not allowed. 1288*2c75bda4Serichkeane return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind); 1289*2c75bda4Serichkeane case OpenACCGangKind::Dim: { 1290*2c75bda4Serichkeane // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel 1291*2c75bda4Serichkeane // construct, or an orphaned loop construct, the gang clause behaves as 1292*2c75bda4Serichkeane // follows. ... The dim argument must be a constant positive integer value 1293*2c75bda4Serichkeane // 1, 2, or 3. 1294*2c75bda4Serichkeane if (!E) 1295*2c75bda4Serichkeane return ExprError(); 1296*2c75bda4Serichkeane ExprResult Res = 1297*2c75bda4Serichkeane S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang, 1298*2c75bda4Serichkeane E->getBeginLoc(), E); 1299*2c75bda4Serichkeane 1300*2c75bda4Serichkeane if (!Res.isUsable()) 1301*2c75bda4Serichkeane return Res; 1302*2c75bda4Serichkeane 1303*2c75bda4Serichkeane if (Res.get()->isInstantiationDependent()) 1304*2c75bda4Serichkeane return Res; 1305*2c75bda4Serichkeane 1306*2c75bda4Serichkeane std::optional<llvm::APSInt> ICE = 1307*2c75bda4Serichkeane Res.get()->getIntegerConstantExpr(S.getASTContext()); 1308*2c75bda4Serichkeane 1309*2c75bda4Serichkeane if (!ICE || *ICE <= 0 || ICE > 3) { 1310*2c75bda4Serichkeane S.Diag(Res.get()->getBeginLoc(), diag::err_acc_gang_dim_value) 1311*2c75bda4Serichkeane << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue(); 1312*2c75bda4Serichkeane return ExprError(); 1313*2c75bda4Serichkeane } 1314*2c75bda4Serichkeane 1315*2c75bda4Serichkeane return ExprResult{ 1316*2c75bda4Serichkeane ConstantExpr::Create(S.getASTContext(), Res.get(), APValue{*ICE})}; 1317*2c75bda4Serichkeane } 1318*2c75bda4Serichkeane } 1319*2c75bda4Serichkeane llvm_unreachable("Unknown gang kind in gang parallel check"); 1320*2c75bda4Serichkeane } 1321*2c75bda4Serichkeane 1322*2c75bda4Serichkeane ExprResult CheckGangKernelsExpr(SemaOpenACC &S, 1323*2c75bda4Serichkeane ArrayRef<const OpenACCClause *> ExistingClauses, 1324*2c75bda4Serichkeane OpenACCDirectiveKind DK, 1325*2c75bda4Serichkeane OpenACCDirectiveKind AssocKind, 1326*2c75bda4Serichkeane OpenACCGangKind GK, Expr *E) { 1327*2c75bda4Serichkeane switch (GK) { 1328*2c75bda4Serichkeane // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels 1329*2c75bda4Serichkeane // construct, the gang clause behaves as follows. ... The dim argument is 1330*2c75bda4Serichkeane // not allowed. 1331*2c75bda4Serichkeane case OpenACCGangKind::Dim: 1332*2c75bda4Serichkeane return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind); 1333*2c75bda4Serichkeane case OpenACCGangKind::Num: { 1334*2c75bda4Serichkeane // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels 1335*2c75bda4Serichkeane // construct, the gang clause behaves as follows. ... An argument with no 1336*2c75bda4Serichkeane // keyword or with num keyword is only allowed when num_gangs does not 1337*2c75bda4Serichkeane // appear on the kernels construct. ... The region of a loop with the gang 1338*2c75bda4Serichkeane // clause may not contain another loop with a gang clause unless within a 1339*2c75bda4Serichkeane // nested compute region. 1340*2c75bda4Serichkeane 1341*2c75bda4Serichkeane // If this is a 'combined' construct, search the list of existing clauses. 1342*2c75bda4Serichkeane // Else we need to search the containing 'kernel'. 1343*2c75bda4Serichkeane auto Collection = isOpenACCCombinedDirectiveKind(DK) 1344*2c75bda4Serichkeane ? ExistingClauses 1345*2c75bda4Serichkeane : S.getActiveComputeConstructInfo().Clauses; 1346*2c75bda4Serichkeane 1347*2c75bda4Serichkeane const auto *Itr = 1348*2c75bda4Serichkeane llvm::find_if(Collection, llvm::IsaPred<OpenACCNumGangsClause>); 1349*2c75bda4Serichkeane 1350*2c75bda4Serichkeane if (Itr != Collection.end()) { 1351*2c75bda4Serichkeane S.Diag(E->getBeginLoc(), diag::err_acc_num_arg_conflict) 1352*2c75bda4Serichkeane << "num" << OpenACCClauseKind::Gang << DK 1353*2c75bda4Serichkeane << HasAssocKind(DK, AssocKind) << AssocKind 1354*2c75bda4Serichkeane << OpenACCClauseKind::NumGangs; 1355*2c75bda4Serichkeane 1356*2c75bda4Serichkeane S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 1357*2c75bda4Serichkeane return ExprError(); 1358*2c75bda4Serichkeane } 1359*2c75bda4Serichkeane return ExprResult{E}; 1360*2c75bda4Serichkeane } 1361*2c75bda4Serichkeane case OpenACCGangKind::Static: 1362*2c75bda4Serichkeane return CheckGangStaticExpr(S, E); 1363*2c75bda4Serichkeane } 1364*2c75bda4Serichkeane llvm_unreachable("Unknown gang kind in gang kernels check"); 1365*2c75bda4Serichkeane } 1366*2c75bda4Serichkeane 1367*2c75bda4Serichkeane ExprResult CheckGangSerialExpr(SemaOpenACC &S, OpenACCDirectiveKind DK, 1368*2c75bda4Serichkeane OpenACCDirectiveKind AssocKind, 1369*2c75bda4Serichkeane OpenACCGangKind GK, Expr *E) { 1370*2c75bda4Serichkeane switch (GK) { 1371*2c75bda4Serichkeane // 'dim' and 'num' don't really make sense on serial, and GCC rejects them 1372*2c75bda4Serichkeane // too, so we disallow them too. 1373*2c75bda4Serichkeane case OpenACCGangKind::Dim: 1374*2c75bda4Serichkeane case OpenACCGangKind::Num: 1375*2c75bda4Serichkeane return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind); 1376*2c75bda4Serichkeane case OpenACCGangKind::Static: 1377*2c75bda4Serichkeane return CheckGangStaticExpr(S, E); 1378*2c75bda4Serichkeane } 1379*2c75bda4Serichkeane llvm_unreachable("Unknown gang kind in gang serial check"); 1380*2c75bda4Serichkeane } 1381*2c75bda4Serichkeane 1382*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause( 1383*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1384*2c75bda4Serichkeane if (DiagIfSeqClause(Clause)) 1385*2c75bda4Serichkeane return nullptr; 1386*2c75bda4Serichkeane 1387*2c75bda4Serichkeane // Restrictions only properly implemented on 'loop'/'combined' constructs, and 1388*2c75bda4Serichkeane // it is the only construct that can do anything with this, so skip/treat as 1389*2c75bda4Serichkeane // unimplemented for the routine constructs. 1390*2c75bda4Serichkeane if (!isDirectiveKindImplemented(Clause.getDirectiveKind())) 1391*2c75bda4Serichkeane return isNotImplemented(); 1392*2c75bda4Serichkeane 1393*2c75bda4Serichkeane Expr *IntExpr = 1394*2c75bda4Serichkeane Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr; 1395*2c75bda4Serichkeane if (IntExpr) { 1396*2c75bda4Serichkeane if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 1397*2c75bda4Serichkeane switch (SemaRef.getActiveComputeConstructInfo().Kind) { 1398*2c75bda4Serichkeane case OpenACCDirectiveKind::Invalid: 1399*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 1400*2c75bda4Serichkeane // No restriction on when 'parallel' can contain an argument. 1401*2c75bda4Serichkeane break; 1402*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 1403*2c75bda4Serichkeane // GCC disallows this, and there is no real good reason for us to permit 1404*2c75bda4Serichkeane // it, so disallow until we come up with a use case that makes sense. 1405*2c75bda4Serichkeane DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector, 1406*2c75bda4Serichkeane Clause.getDirectiveKind(), 1407*2c75bda4Serichkeane SemaRef.getActiveComputeConstructInfo().Kind); 1408*2c75bda4Serichkeane IntExpr = nullptr; 1409*2c75bda4Serichkeane break; 1410*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: { 1411*2c75bda4Serichkeane const auto *Itr = 1412*2c75bda4Serichkeane llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses, 1413*2c75bda4Serichkeane llvm::IsaPred<OpenACCVectorLengthClause>); 1414*2c75bda4Serichkeane if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) { 1415*2c75bda4Serichkeane SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) 1416*2c75bda4Serichkeane << "length" << OpenACCClauseKind::Vector 1417*2c75bda4Serichkeane << Clause.getDirectiveKind() 1418*2c75bda4Serichkeane << HasAssocKind(Clause.getDirectiveKind(), 1419*2c75bda4Serichkeane SemaRef.getActiveComputeConstructInfo().Kind) 1420*2c75bda4Serichkeane << SemaRef.getActiveComputeConstructInfo().Kind 1421*2c75bda4Serichkeane << OpenACCClauseKind::VectorLength; 1422*2c75bda4Serichkeane SemaRef.Diag((*Itr)->getBeginLoc(), 1423*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1424*2c75bda4Serichkeane 1425*2c75bda4Serichkeane IntExpr = nullptr; 1426*2c75bda4Serichkeane } 1427*2c75bda4Serichkeane break; 1428*2c75bda4Serichkeane } 1429*2c75bda4Serichkeane default: 1430*2c75bda4Serichkeane llvm_unreachable("Non compute construct in active compute construct"); 1431*2c75bda4Serichkeane } 1432*2c75bda4Serichkeane } else { 1433*2c75bda4Serichkeane if (Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) { 1434*2c75bda4Serichkeane DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector, 1435*2c75bda4Serichkeane Clause.getDirectiveKind(), 1436*2c75bda4Serichkeane SemaRef.getActiveComputeConstructInfo().Kind); 1437*2c75bda4Serichkeane IntExpr = nullptr; 1438*2c75bda4Serichkeane } else if (Clause.getDirectiveKind() == 1439*2c75bda4Serichkeane OpenACCDirectiveKind::KernelsLoop) { 1440*2c75bda4Serichkeane const auto *Itr = llvm::find_if( 1441*2c75bda4Serichkeane ExistingClauses, llvm::IsaPred<OpenACCVectorLengthClause>); 1442*2c75bda4Serichkeane if (Itr != ExistingClauses.end()) { 1443*2c75bda4Serichkeane SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) 1444*2c75bda4Serichkeane << "length" << OpenACCClauseKind::Vector 1445*2c75bda4Serichkeane << Clause.getDirectiveKind() 1446*2c75bda4Serichkeane << HasAssocKind(Clause.getDirectiveKind(), 1447*2c75bda4Serichkeane SemaRef.getActiveComputeConstructInfo().Kind) 1448*2c75bda4Serichkeane << SemaRef.getActiveComputeConstructInfo().Kind 1449*2c75bda4Serichkeane << OpenACCClauseKind::VectorLength; 1450*2c75bda4Serichkeane SemaRef.Diag((*Itr)->getBeginLoc(), 1451*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1452*2c75bda4Serichkeane 1453*2c75bda4Serichkeane IntExpr = nullptr; 1454*2c75bda4Serichkeane } 1455*2c75bda4Serichkeane } 1456*2c75bda4Serichkeane } 1457*2c75bda4Serichkeane } 1458*2c75bda4Serichkeane 1459*2c75bda4Serichkeane if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 1460*2c75bda4Serichkeane // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not 1461*2c75bda4Serichkeane // contain a loop with a gang, worker, or vector clause unless within a 1462*2c75bda4Serichkeane // nested compute region. 1463*2c75bda4Serichkeane if (SemaRef.LoopVectorClauseLoc.isValid()) { 1464*2c75bda4Serichkeane // This handles the 'inner loop' diagnostic, but we cannot set that we're 1465*2c75bda4Serichkeane // on one of these until we get to the end of the construct. 1466*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1467*2c75bda4Serichkeane << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector 1468*2c75bda4Serichkeane << /*skip kernels construct info*/ 0; 1469*2c75bda4Serichkeane SemaRef.Diag(SemaRef.LoopVectorClauseLoc, 1470*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1471*2c75bda4Serichkeane return nullptr; 1472*2c75bda4Serichkeane } 1473*2c75bda4Serichkeane } 1474*2c75bda4Serichkeane 1475*2c75bda4Serichkeane return OpenACCVectorClause::Create(Ctx, Clause.getBeginLoc(), 1476*2c75bda4Serichkeane Clause.getLParenLoc(), IntExpr, 1477*2c75bda4Serichkeane Clause.getEndLoc()); 1478*2c75bda4Serichkeane } 1479*2c75bda4Serichkeane 1480*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause( 1481*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1482*2c75bda4Serichkeane if (DiagIfSeqClause(Clause)) 1483*2c75bda4Serichkeane return nullptr; 1484*2c75bda4Serichkeane 1485*2c75bda4Serichkeane // Restrictions only properly implemented on 'loop'/'combined' constructs, and 1486*2c75bda4Serichkeane // it is the only construct that can do anything with this, so skip/treat as 1487*2c75bda4Serichkeane // unimplemented for the routine constructs. 1488*2c75bda4Serichkeane if (!isDirectiveKindImplemented(Clause.getDirectiveKind())) 1489*2c75bda4Serichkeane return isNotImplemented(); 1490*2c75bda4Serichkeane 1491*2c75bda4Serichkeane Expr *IntExpr = 1492*2c75bda4Serichkeane Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr; 1493*2c75bda4Serichkeane 1494*2c75bda4Serichkeane if (IntExpr) { 1495*2c75bda4Serichkeane if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 1496*2c75bda4Serichkeane switch (SemaRef.getActiveComputeConstructInfo().Kind) { 1497*2c75bda4Serichkeane case OpenACCDirectiveKind::Invalid: 1498*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 1499*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 1500*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 1501*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 1502*2c75bda4Serichkeane DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num, 1503*2c75bda4Serichkeane OpenACCClauseKind::Worker, Clause.getDirectiveKind(), 1504*2c75bda4Serichkeane SemaRef.getActiveComputeConstructInfo().Kind); 1505*2c75bda4Serichkeane IntExpr = nullptr; 1506*2c75bda4Serichkeane break; 1507*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 1508*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: { 1509*2c75bda4Serichkeane const auto *Itr = 1510*2c75bda4Serichkeane llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses, 1511*2c75bda4Serichkeane llvm::IsaPred<OpenACCNumWorkersClause>); 1512*2c75bda4Serichkeane if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) { 1513*2c75bda4Serichkeane SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) 1514*2c75bda4Serichkeane << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind() 1515*2c75bda4Serichkeane << HasAssocKind(Clause.getDirectiveKind(), 1516*2c75bda4Serichkeane SemaRef.getActiveComputeConstructInfo().Kind) 1517*2c75bda4Serichkeane << SemaRef.getActiveComputeConstructInfo().Kind 1518*2c75bda4Serichkeane << OpenACCClauseKind::NumWorkers; 1519*2c75bda4Serichkeane SemaRef.Diag((*Itr)->getBeginLoc(), 1520*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1521*2c75bda4Serichkeane 1522*2c75bda4Serichkeane IntExpr = nullptr; 1523*2c75bda4Serichkeane } 1524*2c75bda4Serichkeane break; 1525*2c75bda4Serichkeane } 1526*2c75bda4Serichkeane default: 1527*2c75bda4Serichkeane llvm_unreachable("Non compute construct in active compute construct"); 1528*2c75bda4Serichkeane } 1529*2c75bda4Serichkeane } else { 1530*2c75bda4Serichkeane if (Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop || 1531*2c75bda4Serichkeane Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) { 1532*2c75bda4Serichkeane DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num, 1533*2c75bda4Serichkeane OpenACCClauseKind::Worker, Clause.getDirectiveKind(), 1534*2c75bda4Serichkeane SemaRef.getActiveComputeConstructInfo().Kind); 1535*2c75bda4Serichkeane IntExpr = nullptr; 1536*2c75bda4Serichkeane } else { 1537*2c75bda4Serichkeane assert(Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop && 1538*2c75bda4Serichkeane "Unknown combined directive kind?"); 1539*2c75bda4Serichkeane const auto *Itr = llvm::find_if(ExistingClauses, 1540*2c75bda4Serichkeane llvm::IsaPred<OpenACCNumWorkersClause>); 1541*2c75bda4Serichkeane if (Itr != ExistingClauses.end()) { 1542*2c75bda4Serichkeane SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) 1543*2c75bda4Serichkeane << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind() 1544*2c75bda4Serichkeane << HasAssocKind(Clause.getDirectiveKind(), 1545*2c75bda4Serichkeane SemaRef.getActiveComputeConstructInfo().Kind) 1546*2c75bda4Serichkeane << SemaRef.getActiveComputeConstructInfo().Kind 1547*2c75bda4Serichkeane << OpenACCClauseKind::NumWorkers; 1548*2c75bda4Serichkeane SemaRef.Diag((*Itr)->getBeginLoc(), 1549*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1550*2c75bda4Serichkeane 1551*2c75bda4Serichkeane IntExpr = nullptr; 1552*2c75bda4Serichkeane } 1553*2c75bda4Serichkeane } 1554*2c75bda4Serichkeane } 1555*2c75bda4Serichkeane } 1556*2c75bda4Serichkeane 1557*2c75bda4Serichkeane if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 1558*2c75bda4Serichkeane // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not 1559*2c75bda4Serichkeane // contain a loop with a gang or worker clause unless within a nested 1560*2c75bda4Serichkeane // compute region. 1561*2c75bda4Serichkeane if (SemaRef.LoopWorkerClauseLoc.isValid()) { 1562*2c75bda4Serichkeane // This handles the 'inner loop' diagnostic, but we cannot set that we're 1563*2c75bda4Serichkeane // on one of these until we get to the end of the construct. 1564*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1565*2c75bda4Serichkeane << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker 1566*2c75bda4Serichkeane << /*skip kernels construct info*/ 0; 1567*2c75bda4Serichkeane SemaRef.Diag(SemaRef.LoopWorkerClauseLoc, 1568*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1569*2c75bda4Serichkeane return nullptr; 1570*2c75bda4Serichkeane } 1571*2c75bda4Serichkeane 1572*2c75bda4Serichkeane // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not 1573*2c75bda4Serichkeane // contain a loop with a gang, worker, or vector clause unless within a 1574*2c75bda4Serichkeane // nested compute region. 1575*2c75bda4Serichkeane if (SemaRef.LoopVectorClauseLoc.isValid()) { 1576*2c75bda4Serichkeane // This handles the 'inner loop' diagnostic, but we cannot set that we're 1577*2c75bda4Serichkeane // on one of these until we get to the end of the construct. 1578*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1579*2c75bda4Serichkeane << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector 1580*2c75bda4Serichkeane << /*skip kernels construct info*/ 0; 1581*2c75bda4Serichkeane SemaRef.Diag(SemaRef.LoopVectorClauseLoc, 1582*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1583*2c75bda4Serichkeane return nullptr; 1584*2c75bda4Serichkeane } 1585*2c75bda4Serichkeane } 1586*2c75bda4Serichkeane 1587*2c75bda4Serichkeane return OpenACCWorkerClause::Create(Ctx, Clause.getBeginLoc(), 1588*2c75bda4Serichkeane Clause.getLParenLoc(), IntExpr, 1589*2c75bda4Serichkeane Clause.getEndLoc()); 1590*2c75bda4Serichkeane } 1591*2c75bda4Serichkeane 1592*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause( 1593*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1594*2c75bda4Serichkeane if (DiagIfSeqClause(Clause)) 1595*2c75bda4Serichkeane return nullptr; 1596*2c75bda4Serichkeane 1597*2c75bda4Serichkeane // Restrictions only properly implemented on 'loop' constructs, and it is 1598*2c75bda4Serichkeane // the only construct that can do anything with this, so skip/treat as 1599*2c75bda4Serichkeane // unimplemented for the combined constructs. 1600*2c75bda4Serichkeane if (!isDirectiveKindImplemented(Clause.getDirectiveKind())) 1601*2c75bda4Serichkeane return isNotImplemented(); 1602*2c75bda4Serichkeane 1603*2c75bda4Serichkeane // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop 1604*2c75bda4Serichkeane // directive that has a gang clause and is within a compute construct that has 1605*2c75bda4Serichkeane // a num_gangs clause with more than one explicit argument. 1606*2c75bda4Serichkeane if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop && 1607*2c75bda4Serichkeane SemaRef.getActiveComputeConstructInfo().Kind != 1608*2c75bda4Serichkeane OpenACCDirectiveKind::Invalid) || 1609*2c75bda4Serichkeane isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 1610*2c75bda4Serichkeane // num_gangs clause on the active compute construct. 1611*2c75bda4Serichkeane auto ActiveComputeConstructContainer = 1612*2c75bda4Serichkeane isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) 1613*2c75bda4Serichkeane ? ExistingClauses 1614*2c75bda4Serichkeane : SemaRef.getActiveComputeConstructInfo().Clauses; 1615*2c75bda4Serichkeane auto *NumGangsClauseItr = llvm::find_if( 1616*2c75bda4Serichkeane ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>); 1617*2c75bda4Serichkeane 1618*2c75bda4Serichkeane if (NumGangsClauseItr != ActiveComputeConstructContainer.end() && 1619*2c75bda4Serichkeane cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() > 1620*2c75bda4Serichkeane 1) { 1621*2c75bda4Serichkeane auto *ReductionClauseItr = 1622*2c75bda4Serichkeane llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>); 1623*2c75bda4Serichkeane 1624*2c75bda4Serichkeane if (ReductionClauseItr != ExistingClauses.end()) { 1625*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), 1626*2c75bda4Serichkeane diag::err_acc_gang_reduction_numgangs_conflict) 1627*2c75bda4Serichkeane << OpenACCClauseKind::Gang << OpenACCClauseKind::Reduction 1628*2c75bda4Serichkeane << Clause.getDirectiveKind() 1629*2c75bda4Serichkeane << isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()); 1630*2c75bda4Serichkeane SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(), 1631*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1632*2c75bda4Serichkeane SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(), 1633*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1634*2c75bda4Serichkeane return nullptr; 1635*2c75bda4Serichkeane } 1636*2c75bda4Serichkeane } 1637*2c75bda4Serichkeane } 1638*2c75bda4Serichkeane 1639*2c75bda4Serichkeane llvm::SmallVector<OpenACCGangKind> GangKinds; 1640*2c75bda4Serichkeane llvm::SmallVector<Expr *> IntExprs; 1641*2c75bda4Serichkeane 1642*2c75bda4Serichkeane // Store the existing locations, so we can do duplicate checking. Index is 1643*2c75bda4Serichkeane // the int-value of the OpenACCGangKind enum. 1644*2c75bda4Serichkeane SourceLocation ExistingElemLoc[3]; 1645*2c75bda4Serichkeane 1646*2c75bda4Serichkeane for (unsigned I = 0; I < Clause.getIntExprs().size(); ++I) { 1647*2c75bda4Serichkeane OpenACCGangKind GK = Clause.getGangKinds()[I]; 1648*2c75bda4Serichkeane ExprResult ER = 1649*2c75bda4Serichkeane SemaRef.CheckGangExpr(ExistingClauses, Clause.getDirectiveKind(), GK, 1650*2c75bda4Serichkeane Clause.getIntExprs()[I]); 1651*2c75bda4Serichkeane 1652*2c75bda4Serichkeane if (!ER.isUsable()) 1653*2c75bda4Serichkeane continue; 1654*2c75bda4Serichkeane 1655*2c75bda4Serichkeane // OpenACC 3.3 2.9: 'gang-arg-list' may have at most one num, one dim, and 1656*2c75bda4Serichkeane // one static argument. 1657*2c75bda4Serichkeane if (ExistingElemLoc[static_cast<unsigned>(GK)].isValid()) { 1658*2c75bda4Serichkeane SemaRef.Diag(ER.get()->getBeginLoc(), diag::err_acc_gang_multiple_elt) 1659*2c75bda4Serichkeane << static_cast<unsigned>(GK); 1660*2c75bda4Serichkeane SemaRef.Diag(ExistingElemLoc[static_cast<unsigned>(GK)], 1661*2c75bda4Serichkeane diag::note_acc_previous_expr_here); 1662*2c75bda4Serichkeane continue; 1663*2c75bda4Serichkeane } 1664*2c75bda4Serichkeane 1665*2c75bda4Serichkeane ExistingElemLoc[static_cast<unsigned>(GK)] = ER.get()->getBeginLoc(); 1666*2c75bda4Serichkeane GangKinds.push_back(GK); 1667*2c75bda4Serichkeane IntExprs.push_back(ER.get()); 1668*2c75bda4Serichkeane } 1669*2c75bda4Serichkeane 1670*2c75bda4Serichkeane if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 1671*2c75bda4Serichkeane // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels 1672*2c75bda4Serichkeane // construct, the gang clause behaves as follows. ... The region of a loop 1673*2c75bda4Serichkeane // with a gang clause may not contain another loop with a gang clause unless 1674*2c75bda4Serichkeane // within a nested compute region. 1675*2c75bda4Serichkeane if (SemaRef.LoopGangClauseOnKernel.Loc.isValid()) { 1676*2c75bda4Serichkeane // This handles the 'inner loop' diagnostic, but we cannot set that we're 1677*2c75bda4Serichkeane // on one of these until we get to the end of the construct. 1678*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1679*2c75bda4Serichkeane << OpenACCClauseKind::Gang << OpenACCClauseKind::Gang 1680*2c75bda4Serichkeane << /*kernels construct info*/ 1 1681*2c75bda4Serichkeane << SemaRef.LoopGangClauseOnKernel.DirKind; 1682*2c75bda4Serichkeane SemaRef.Diag(SemaRef.LoopGangClauseOnKernel.Loc, 1683*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1684*2c75bda4Serichkeane return nullptr; 1685*2c75bda4Serichkeane } 1686*2c75bda4Serichkeane 1687*2c75bda4Serichkeane // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not 1688*2c75bda4Serichkeane // contain a loop with a gang or worker clause unless within a nested 1689*2c75bda4Serichkeane // compute region. 1690*2c75bda4Serichkeane if (SemaRef.LoopWorkerClauseLoc.isValid()) { 1691*2c75bda4Serichkeane // This handles the 'inner loop' diagnostic, but we cannot set that we're 1692*2c75bda4Serichkeane // on one of these until we get to the end of the construct. 1693*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1694*2c75bda4Serichkeane << OpenACCClauseKind::Gang << OpenACCClauseKind::Worker 1695*2c75bda4Serichkeane << /*!kernels construct info*/ 0; 1696*2c75bda4Serichkeane SemaRef.Diag(SemaRef.LoopWorkerClauseLoc, 1697*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1698*2c75bda4Serichkeane return nullptr; 1699*2c75bda4Serichkeane } 1700*2c75bda4Serichkeane 1701*2c75bda4Serichkeane // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not 1702*2c75bda4Serichkeane // contain a loop with a gang, worker, or vector clause unless within a 1703*2c75bda4Serichkeane // nested compute region. 1704*2c75bda4Serichkeane if (SemaRef.LoopVectorClauseLoc.isValid()) { 1705*2c75bda4Serichkeane // This handles the 'inner loop' diagnostic, but we cannot set that we're 1706*2c75bda4Serichkeane // on one of these until we get to the end of the construct. 1707*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) 1708*2c75bda4Serichkeane << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector 1709*2c75bda4Serichkeane << /*!kernels construct info*/ 0; 1710*2c75bda4Serichkeane SemaRef.Diag(SemaRef.LoopVectorClauseLoc, 1711*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1712*2c75bda4Serichkeane return nullptr; 1713*2c75bda4Serichkeane } 1714*2c75bda4Serichkeane } 1715*2c75bda4Serichkeane 1716*2c75bda4Serichkeane return SemaRef.CheckGangClause(Clause.getDirectiveKind(), ExistingClauses, 1717*2c75bda4Serichkeane Clause.getBeginLoc(), Clause.getLParenLoc(), 1718*2c75bda4Serichkeane GangKinds, IntExprs, Clause.getEndLoc()); 1719*2c75bda4Serichkeane } 1720*2c75bda4Serichkeane 1721*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause( 1722*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1723*2c75bda4Serichkeane // There isn't anything to do here, this is only valid on one construct, and 1724*2c75bda4Serichkeane // has no associated rules. 1725*2c75bda4Serichkeane return OpenACCFinalizeClause::Create(Ctx, Clause.getBeginLoc(), 1726*2c75bda4Serichkeane Clause.getEndLoc()); 1727*2c75bda4Serichkeane } 1728*2c75bda4Serichkeane 1729*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause( 1730*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1731*2c75bda4Serichkeane // There isn't anything to do here, this is only valid on one construct, and 1732*2c75bda4Serichkeane // has no associated rules. 1733*2c75bda4Serichkeane return OpenACCIfPresentClause::Create(Ctx, Clause.getBeginLoc(), 1734*2c75bda4Serichkeane Clause.getEndLoc()); 1735*2c75bda4Serichkeane } 1736*2c75bda4Serichkeane 1737*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause( 1738*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1739*2c75bda4Serichkeane // Restrictions only properly implemented on 'loop' constructs and combined , 1740*2c75bda4Serichkeane // and it is the only construct that can do anything with this, so skip/treat 1741*2c75bda4Serichkeane // as unimplemented for the routine constructs. 1742*2c75bda4Serichkeane if (!isDirectiveKindImplemented(Clause.getDirectiveKind())) 1743*2c75bda4Serichkeane return isNotImplemented(); 1744*2c75bda4Serichkeane 1745*2c75bda4Serichkeane // OpenACC 3.3 2.9: 1746*2c75bda4Serichkeane // Only one of the seq, independent, and auto clauses may appear. 1747*2c75bda4Serichkeane const auto *Itr = 1748*2c75bda4Serichkeane llvm::find_if(ExistingClauses, 1749*2c75bda4Serichkeane llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>); 1750*2c75bda4Serichkeane if (Itr != ExistingClauses.end()) { 1751*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict) 1752*2c75bda4Serichkeane << Clause.getClauseKind() << Clause.getDirectiveKind(); 1753*2c75bda4Serichkeane SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 1754*2c75bda4Serichkeane return nullptr; 1755*2c75bda4Serichkeane } 1756*2c75bda4Serichkeane 1757*2c75bda4Serichkeane // OpenACC 3.3 2.9: 1758*2c75bda4Serichkeane // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause 1759*2c75bda4Serichkeane // appears. 1760*2c75bda4Serichkeane Itr = llvm::find_if(ExistingClauses, 1761*2c75bda4Serichkeane llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause, 1762*2c75bda4Serichkeane OpenACCVectorClause>); 1763*2c75bda4Serichkeane 1764*2c75bda4Serichkeane if (Itr != ExistingClauses.end()) { 1765*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine) 1766*2c75bda4Serichkeane << Clause.getClauseKind() << (*Itr)->getClauseKind() 1767*2c75bda4Serichkeane << Clause.getDirectiveKind(); 1768*2c75bda4Serichkeane SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 1769*2c75bda4Serichkeane return nullptr; 1770*2c75bda4Serichkeane } 1771*2c75bda4Serichkeane 1772*2c75bda4Serichkeane return OpenACCSeqClause::Create(Ctx, Clause.getBeginLoc(), 1773*2c75bda4Serichkeane Clause.getEndLoc()); 1774*2c75bda4Serichkeane } 1775*2c75bda4Serichkeane 1776*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause( 1777*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1778*2c75bda4Serichkeane // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop 1779*2c75bda4Serichkeane // directive that has a gang clause and is within a compute construct that has 1780*2c75bda4Serichkeane // a num_gangs clause with more than one explicit argument. 1781*2c75bda4Serichkeane if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop && 1782*2c75bda4Serichkeane SemaRef.getActiveComputeConstructInfo().Kind != 1783*2c75bda4Serichkeane OpenACCDirectiveKind::Invalid) || 1784*2c75bda4Serichkeane isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { 1785*2c75bda4Serichkeane // num_gangs clause on the active compute construct. 1786*2c75bda4Serichkeane auto ActiveComputeConstructContainer = 1787*2c75bda4Serichkeane isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) 1788*2c75bda4Serichkeane ? ExistingClauses 1789*2c75bda4Serichkeane : SemaRef.getActiveComputeConstructInfo().Clauses; 1790*2c75bda4Serichkeane auto *NumGangsClauseItr = llvm::find_if( 1791*2c75bda4Serichkeane ActiveComputeConstructContainer, llvm::IsaPred<OpenACCNumGangsClause>); 1792*2c75bda4Serichkeane 1793*2c75bda4Serichkeane if (NumGangsClauseItr != ActiveComputeConstructContainer.end() && 1794*2c75bda4Serichkeane cast<OpenACCNumGangsClause>(*NumGangsClauseItr)->getIntExprs().size() > 1795*2c75bda4Serichkeane 1) { 1796*2c75bda4Serichkeane auto *GangClauseItr = 1797*2c75bda4Serichkeane llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCGangClause>); 1798*2c75bda4Serichkeane 1799*2c75bda4Serichkeane if (GangClauseItr != ExistingClauses.end()) { 1800*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), 1801*2c75bda4Serichkeane diag::err_acc_gang_reduction_numgangs_conflict) 1802*2c75bda4Serichkeane << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang 1803*2c75bda4Serichkeane << Clause.getDirectiveKind() 1804*2c75bda4Serichkeane << isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()); 1805*2c75bda4Serichkeane SemaRef.Diag((*GangClauseItr)->getBeginLoc(), 1806*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1807*2c75bda4Serichkeane SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(), 1808*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 1809*2c75bda4Serichkeane return nullptr; 1810*2c75bda4Serichkeane } 1811*2c75bda4Serichkeane } 1812*2c75bda4Serichkeane } 1813*2c75bda4Serichkeane 1814*2c75bda4Serichkeane // OpenACC3.3 Section 2.9.11: If a variable is involved in a reduction that 1815*2c75bda4Serichkeane // spans multiple nested loops where two or more of those loops have 1816*2c75bda4Serichkeane // associated loop directives, a reduction clause containing that variable 1817*2c75bda4Serichkeane // must appear on each of those loop directives. 1818*2c75bda4Serichkeane // 1819*2c75bda4Serichkeane // This can't really be implemented in the CFE, as this requires a level of 1820*2c75bda4Serichkeane // rechability/useage analysis that we're not really wanting to get into. 1821*2c75bda4Serichkeane // Additionally, I'm alerted that this restriction is one that the middle-end 1822*2c75bda4Serichkeane // can just 'figure out' as an extension and isn't really necessary. 1823*2c75bda4Serichkeane // 1824*2c75bda4Serichkeane // OpenACC3.3 Section 2.9.11: Every 'var' in a reduction clause appearing on 1825*2c75bda4Serichkeane // an orphaned loop construct must be private. 1826*2c75bda4Serichkeane // 1827*2c75bda4Serichkeane // This again is something we cannot really diagnose, as it requires we see 1828*2c75bda4Serichkeane // all the uses/scopes of all variables referenced. The middle end/MLIR might 1829*2c75bda4Serichkeane // be able to diagnose this. 1830*2c75bda4Serichkeane 1831*2c75bda4Serichkeane // OpenACC 3.3 Section 2.5.4: 1832*2c75bda4Serichkeane // A reduction clause may not appear on a parallel construct with a 1833*2c75bda4Serichkeane // num_gangs clause that has more than one argument. 1834*2c75bda4Serichkeane if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || 1835*2c75bda4Serichkeane Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) { 1836*2c75bda4Serichkeane auto NumGangsClauses = llvm::make_filter_range( 1837*2c75bda4Serichkeane ExistingClauses, llvm::IsaPred<OpenACCNumGangsClause>); 1838*2c75bda4Serichkeane 1839*2c75bda4Serichkeane for (auto *NGC : NumGangsClauses) { 1840*2c75bda4Serichkeane unsigned NumExprs = 1841*2c75bda4Serichkeane cast<OpenACCNumGangsClause>(NGC)->getIntExprs().size(); 1842*2c75bda4Serichkeane 1843*2c75bda4Serichkeane if (NumExprs > 1) { 1844*2c75bda4Serichkeane SemaRef.Diag(Clause.getBeginLoc(), 1845*2c75bda4Serichkeane diag::err_acc_reduction_num_gangs_conflict) 1846*2c75bda4Serichkeane << /*>1 arg in first loc=*/0 << Clause.getClauseKind() 1847*2c75bda4Serichkeane << Clause.getDirectiveKind() << OpenACCClauseKind::NumGangs; 1848*2c75bda4Serichkeane SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here); 1849*2c75bda4Serichkeane return nullptr; 1850*2c75bda4Serichkeane } 1851*2c75bda4Serichkeane } 1852*2c75bda4Serichkeane } 1853*2c75bda4Serichkeane 1854*2c75bda4Serichkeane SmallVector<Expr *> ValidVars; 1855*2c75bda4Serichkeane 1856*2c75bda4Serichkeane for (Expr *Var : Clause.getVarList()) { 1857*2c75bda4Serichkeane ExprResult Res = SemaRef.CheckReductionVar(Clause.getDirectiveKind(), 1858*2c75bda4Serichkeane Clause.getReductionOp(), Var); 1859*2c75bda4Serichkeane 1860*2c75bda4Serichkeane if (Res.isUsable()) 1861*2c75bda4Serichkeane ValidVars.push_back(Res.get()); 1862*2c75bda4Serichkeane } 1863*2c75bda4Serichkeane 1864*2c75bda4Serichkeane return SemaRef.CheckReductionClause( 1865*2c75bda4Serichkeane ExistingClauses, Clause.getDirectiveKind(), Clause.getBeginLoc(), 1866*2c75bda4Serichkeane Clause.getLParenLoc(), Clause.getReductionOp(), ValidVars, 1867*2c75bda4Serichkeane Clause.getEndLoc()); 1868*2c75bda4Serichkeane } 1869*2c75bda4Serichkeane 1870*2c75bda4Serichkeane OpenACCClause *SemaOpenACCClauseVisitor::VisitCollapseClause( 1871*2c75bda4Serichkeane SemaOpenACC::OpenACCParsedClause &Clause) { 1872*2c75bda4Serichkeane // Duplicates here are not really sensible. We could possible permit 1873*2c75bda4Serichkeane // multiples if they all had the same value, but there isn't really a good 1874*2c75bda4Serichkeane // reason to do so. Also, this simplifies the suppression of duplicates, in 1875*2c75bda4Serichkeane // that we know if we 'find' one after instantiation, that it is the same 1876*2c75bda4Serichkeane // clause, which simplifies instantiation/checking/etc. 1877*2c75bda4Serichkeane if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 1878*2c75bda4Serichkeane return nullptr; 1879*2c75bda4Serichkeane 1880*2c75bda4Serichkeane ExprResult LoopCount = SemaRef.CheckCollapseLoopCount(Clause.getLoopCount()); 1881*2c75bda4Serichkeane 1882*2c75bda4Serichkeane if (!LoopCount.isUsable()) 1883*2c75bda4Serichkeane return nullptr; 1884*2c75bda4Serichkeane 1885*2c75bda4Serichkeane return OpenACCCollapseClause::Create(Ctx, Clause.getBeginLoc(), 1886*2c75bda4Serichkeane Clause.getLParenLoc(), Clause.isForce(), 1887*2c75bda4Serichkeane LoopCount.get(), Clause.getEndLoc()); 1888*2c75bda4Serichkeane } 1889*2c75bda4Serichkeane 1890*2c75bda4Serichkeane // Return true if the two vars refer to the same variable, for the purposes of 1891*2c75bda4Serichkeane // equality checking. 1892*2c75bda4Serichkeane bool areVarsEqual(Expr *VarExpr1, Expr *VarExpr2) { 1893*2c75bda4Serichkeane if (VarExpr1->isInstantiationDependent() || 1894*2c75bda4Serichkeane VarExpr2->isInstantiationDependent()) 1895*2c75bda4Serichkeane return false; 1896*2c75bda4Serichkeane 1897*2c75bda4Serichkeane VarExpr1 = VarExpr1->IgnoreParenCasts(); 1898*2c75bda4Serichkeane VarExpr2 = VarExpr2->IgnoreParenCasts(); 1899*2c75bda4Serichkeane 1900*2c75bda4Serichkeane // Legal expressions can be: Scalar variable reference, sub-array, array 1901*2c75bda4Serichkeane // element, or composite variable member. 1902*2c75bda4Serichkeane 1903*2c75bda4Serichkeane // Sub-array. 1904*2c75bda4Serichkeane if (isa<ArraySectionExpr>(VarExpr1)) { 1905*2c75bda4Serichkeane auto *Expr2AS = dyn_cast<ArraySectionExpr>(VarExpr2); 1906*2c75bda4Serichkeane if (!Expr2AS) 1907*2c75bda4Serichkeane return false; 1908*2c75bda4Serichkeane 1909*2c75bda4Serichkeane auto *Expr1AS = cast<ArraySectionExpr>(VarExpr1); 1910*2c75bda4Serichkeane 1911*2c75bda4Serichkeane if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase())) 1912*2c75bda4Serichkeane return false; 1913*2c75bda4Serichkeane // We could possibly check to see if the ranges aren't overlapping, but it 1914*2c75bda4Serichkeane // isn't clear that the rules allow this. 1915*2c75bda4Serichkeane return true; 1916*2c75bda4Serichkeane } 1917*2c75bda4Serichkeane 1918*2c75bda4Serichkeane // Array-element. 1919*2c75bda4Serichkeane if (isa<ArraySubscriptExpr>(VarExpr1)) { 1920*2c75bda4Serichkeane auto *Expr2AS = dyn_cast<ArraySubscriptExpr>(VarExpr2); 1921*2c75bda4Serichkeane if (!Expr2AS) 1922*2c75bda4Serichkeane return false; 1923*2c75bda4Serichkeane 1924*2c75bda4Serichkeane auto *Expr1AS = cast<ArraySubscriptExpr>(VarExpr1); 1925*2c75bda4Serichkeane 1926*2c75bda4Serichkeane if (!areVarsEqual(Expr1AS->getBase(), Expr2AS->getBase())) 1927*2c75bda4Serichkeane return false; 1928*2c75bda4Serichkeane 1929*2c75bda4Serichkeane // We could possibly check to see if the elements referenced aren't the 1930*2c75bda4Serichkeane // same, but it isn't clear by reading of the standard that this is allowed 1931*2c75bda4Serichkeane // (and that the 'var' refered to isn't the array). 1932*2c75bda4Serichkeane return true; 1933*2c75bda4Serichkeane } 1934*2c75bda4Serichkeane 1935*2c75bda4Serichkeane // Scalar variable reference, or composite variable. 1936*2c75bda4Serichkeane if (isa<DeclRefExpr>(VarExpr1)) { 1937*2c75bda4Serichkeane auto *Expr2DRE = dyn_cast<DeclRefExpr>(VarExpr2); 1938*2c75bda4Serichkeane if (!Expr2DRE) 1939*2c75bda4Serichkeane return false; 1940*2c75bda4Serichkeane 1941*2c75bda4Serichkeane auto *Expr1DRE = cast<DeclRefExpr>(VarExpr1); 1942*2c75bda4Serichkeane 1943*2c75bda4Serichkeane return Expr1DRE->getDecl()->getMostRecentDecl() == 1944*2c75bda4Serichkeane Expr2DRE->getDecl()->getMostRecentDecl(); 1945*2c75bda4Serichkeane } 1946*2c75bda4Serichkeane 1947*2c75bda4Serichkeane llvm_unreachable("Unknown variable type encountered"); 1948*2c75bda4Serichkeane } 1949*2c75bda4Serichkeane } // namespace 1950*2c75bda4Serichkeane 1951*2c75bda4Serichkeane OpenACCClause * 1952*2c75bda4Serichkeane SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses, 1953*2c75bda4Serichkeane OpenACCParsedClause &Clause) { 1954*2c75bda4Serichkeane if (Clause.getClauseKind() == OpenACCClauseKind::Invalid) 1955*2c75bda4Serichkeane return nullptr; 1956*2c75bda4Serichkeane 1957*2c75bda4Serichkeane // Diagnose that we don't support this clause on this directive. 1958*2c75bda4Serichkeane if (!doesClauseApplyToDirective(Clause.getDirectiveKind(), 1959*2c75bda4Serichkeane Clause.getClauseKind())) { 1960*2c75bda4Serichkeane Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment) 1961*2c75bda4Serichkeane << Clause.getDirectiveKind() << Clause.getClauseKind(); 1962*2c75bda4Serichkeane return nullptr; 1963*2c75bda4Serichkeane } 1964*2c75bda4Serichkeane 1965*2c75bda4Serichkeane if (const auto *DevTypeClause = 1966*2c75bda4Serichkeane llvm::find_if(ExistingClauses, 1967*2c75bda4Serichkeane [&](const OpenACCClause *C) { 1968*2c75bda4Serichkeane return isa<OpenACCDeviceTypeClause>(C); 1969*2c75bda4Serichkeane }); 1970*2c75bda4Serichkeane DevTypeClause != ExistingClauses.end()) { 1971*2c75bda4Serichkeane if (checkValidAfterDeviceType( 1972*2c75bda4Serichkeane *this, *cast<OpenACCDeviceTypeClause>(*DevTypeClause), Clause)) 1973*2c75bda4Serichkeane return nullptr; 1974*2c75bda4Serichkeane } 1975*2c75bda4Serichkeane 1976*2c75bda4Serichkeane SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses}; 1977*2c75bda4Serichkeane OpenACCClause *Result = Visitor.Visit(Clause); 1978*2c75bda4Serichkeane assert((!Result || Result->getClauseKind() == Clause.getClauseKind()) && 1979*2c75bda4Serichkeane "Created wrong clause?"); 1980*2c75bda4Serichkeane 1981*2c75bda4Serichkeane if (Visitor.diagNotImplemented()) 1982*2c75bda4Serichkeane Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented) 1983*2c75bda4Serichkeane << Clause.getClauseKind(); 1984*2c75bda4Serichkeane 1985*2c75bda4Serichkeane return Result; 1986*2c75bda4Serichkeane 1987*2c75bda4Serichkeane } 1988*2c75bda4Serichkeane 1989*2c75bda4Serichkeane /// OpenACC 3.3 section 2.5.15: 1990*2c75bda4Serichkeane /// At a mininmum, the supported data types include ... the numerical data types 1991*2c75bda4Serichkeane /// in C, C++, and Fortran. 1992*2c75bda4Serichkeane /// 1993*2c75bda4Serichkeane /// If the reduction var is a composite variable, each 1994*2c75bda4Serichkeane /// member of the composite variable must be a supported datatype for the 1995*2c75bda4Serichkeane /// reduction operation. 1996*2c75bda4Serichkeane ExprResult SemaOpenACC::CheckReductionVar(OpenACCDirectiveKind DirectiveKind, 1997*2c75bda4Serichkeane OpenACCReductionOperator ReductionOp, 1998*2c75bda4Serichkeane Expr *VarExpr) { 1999*2c75bda4Serichkeane VarExpr = VarExpr->IgnoreParenCasts(); 2000*2c75bda4Serichkeane 2001*2c75bda4Serichkeane auto TypeIsValid = [](QualType Ty) { 2002*2c75bda4Serichkeane return Ty->isDependentType() || Ty->isScalarType(); 2003*2c75bda4Serichkeane }; 2004*2c75bda4Serichkeane 2005*2c75bda4Serichkeane if (isa<ArraySectionExpr>(VarExpr)) { 2006*2c75bda4Serichkeane Expr *ASExpr = VarExpr; 2007*2c75bda4Serichkeane QualType BaseTy = ArraySectionExpr::getBaseOriginalType(ASExpr); 2008*2c75bda4Serichkeane QualType EltTy = getASTContext().getBaseElementType(BaseTy); 2009*2c75bda4Serichkeane 2010*2c75bda4Serichkeane if (!TypeIsValid(EltTy)) { 2011*2c75bda4Serichkeane Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type) 2012*2c75bda4Serichkeane << EltTy << /*Sub array base type*/ 1; 2013*2c75bda4Serichkeane return ExprError(); 2014*2c75bda4Serichkeane } 2015*2c75bda4Serichkeane } else if (auto *RD = VarExpr->getType()->getAsRecordDecl()) { 2016*2c75bda4Serichkeane if (!RD->isStruct() && !RD->isClass()) { 2017*2c75bda4Serichkeane Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) 2018*2c75bda4Serichkeane << /*not class or struct*/ 0 << VarExpr->getType(); 2019*2c75bda4Serichkeane return ExprError(); 2020*2c75bda4Serichkeane } 2021*2c75bda4Serichkeane 2022*2c75bda4Serichkeane if (!RD->isCompleteDefinition()) { 2023*2c75bda4Serichkeane Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) 2024*2c75bda4Serichkeane << /*incomplete*/ 1 << VarExpr->getType(); 2025*2c75bda4Serichkeane return ExprError(); 2026*2c75bda4Serichkeane } 2027*2c75bda4Serichkeane if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD); 2028*2c75bda4Serichkeane CXXRD && !CXXRD->isAggregate()) { 2029*2c75bda4Serichkeane Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) 2030*2c75bda4Serichkeane << /*aggregate*/ 2 << VarExpr->getType(); 2031*2c75bda4Serichkeane return ExprError(); 2032*2c75bda4Serichkeane } 2033*2c75bda4Serichkeane 2034*2c75bda4Serichkeane for (FieldDecl *FD : RD->fields()) { 2035*2c75bda4Serichkeane if (!TypeIsValid(FD->getType())) { 2036*2c75bda4Serichkeane Diag(VarExpr->getExprLoc(), 2037*2c75bda4Serichkeane diag::err_acc_reduction_composite_member_type); 2038*2c75bda4Serichkeane Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc); 2039*2c75bda4Serichkeane return ExprError(); 2040*2c75bda4Serichkeane } 2041*2c75bda4Serichkeane } 2042*2c75bda4Serichkeane } else if (!TypeIsValid(VarExpr->getType())) { 2043*2c75bda4Serichkeane Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type) 2044*2c75bda4Serichkeane << VarExpr->getType() << /*Sub array base type*/ 0; 2045*2c75bda4Serichkeane return ExprError(); 2046*2c75bda4Serichkeane } 2047*2c75bda4Serichkeane 2048*2c75bda4Serichkeane // OpenACC3.3: 2.9.11: Reduction clauses on nested constructs for the same 2049*2c75bda4Serichkeane // reduction 'var' must have the same reduction operator. 2050*2c75bda4Serichkeane if (!VarExpr->isInstantiationDependent()) { 2051*2c75bda4Serichkeane 2052*2c75bda4Serichkeane for (const OpenACCReductionClause *RClause : ActiveReductionClauses) { 2053*2c75bda4Serichkeane if (RClause->getReductionOp() == ReductionOp) 2054*2c75bda4Serichkeane break; 2055*2c75bda4Serichkeane 2056*2c75bda4Serichkeane for (Expr *OldVarExpr : RClause->getVarList()) { 2057*2c75bda4Serichkeane if (OldVarExpr->isInstantiationDependent()) 2058*2c75bda4Serichkeane continue; 2059*2c75bda4Serichkeane 2060*2c75bda4Serichkeane if (areVarsEqual(VarExpr, OldVarExpr)) { 2061*2c75bda4Serichkeane Diag(VarExpr->getExprLoc(), diag::err_reduction_op_mismatch) 2062*2c75bda4Serichkeane << ReductionOp << RClause->getReductionOp(); 2063*2c75bda4Serichkeane Diag(OldVarExpr->getExprLoc(), diag::note_acc_previous_clause_here); 2064*2c75bda4Serichkeane return ExprError(); 2065*2c75bda4Serichkeane } 2066*2c75bda4Serichkeane } 2067*2c75bda4Serichkeane } 2068*2c75bda4Serichkeane } 2069*2c75bda4Serichkeane 2070*2c75bda4Serichkeane return VarExpr; 2071*2c75bda4Serichkeane } 2072*2c75bda4Serichkeane 2073*2c75bda4Serichkeane ExprResult SemaOpenACC::CheckTileSizeExpr(Expr *SizeExpr) { 2074*2c75bda4Serichkeane if (!SizeExpr) 2075*2c75bda4Serichkeane return ExprError(); 2076*2c75bda4Serichkeane 2077*2c75bda4Serichkeane assert((SizeExpr->isInstantiationDependent() || 2078*2c75bda4Serichkeane SizeExpr->getType()->isIntegerType()) && 2079*2c75bda4Serichkeane "size argument non integer?"); 2080*2c75bda4Serichkeane 2081*2c75bda4Serichkeane // If dependent, or an asterisk, the expression is fine. 2082*2c75bda4Serichkeane if (SizeExpr->isInstantiationDependent() || 2083*2c75bda4Serichkeane isa<OpenACCAsteriskSizeExpr>(SizeExpr)) 2084*2c75bda4Serichkeane return ExprResult{SizeExpr}; 2085*2c75bda4Serichkeane 2086*2c75bda4Serichkeane std::optional<llvm::APSInt> ICE = 2087*2c75bda4Serichkeane SizeExpr->getIntegerConstantExpr(getASTContext()); 2088*2c75bda4Serichkeane 2089*2c75bda4Serichkeane // OpenACC 3.3 2.9.8 2090*2c75bda4Serichkeane // where each tile size is a constant positive integer expression or asterisk. 2091*2c75bda4Serichkeane if (!ICE || *ICE <= 0) { 2092*2c75bda4Serichkeane Diag(SizeExpr->getBeginLoc(), diag::err_acc_size_expr_value) 2093*2c75bda4Serichkeane << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue(); 2094*2c75bda4Serichkeane return ExprError(); 2095*2c75bda4Serichkeane } 2096*2c75bda4Serichkeane 2097*2c75bda4Serichkeane return ExprResult{ 2098*2c75bda4Serichkeane ConstantExpr::Create(getASTContext(), SizeExpr, APValue{*ICE})}; 2099*2c75bda4Serichkeane } 2100*2c75bda4Serichkeane 2101*2c75bda4Serichkeane ExprResult SemaOpenACC::CheckCollapseLoopCount(Expr *LoopCount) { 2102*2c75bda4Serichkeane if (!LoopCount) 2103*2c75bda4Serichkeane return ExprError(); 2104*2c75bda4Serichkeane 2105*2c75bda4Serichkeane assert((LoopCount->isInstantiationDependent() || 2106*2c75bda4Serichkeane LoopCount->getType()->isIntegerType()) && 2107*2c75bda4Serichkeane "Loop argument non integer?"); 2108*2c75bda4Serichkeane 2109*2c75bda4Serichkeane // If this is dependent, there really isn't anything we can check. 2110*2c75bda4Serichkeane if (LoopCount->isInstantiationDependent()) 2111*2c75bda4Serichkeane return ExprResult{LoopCount}; 2112*2c75bda4Serichkeane 2113*2c75bda4Serichkeane std::optional<llvm::APSInt> ICE = 2114*2c75bda4Serichkeane LoopCount->getIntegerConstantExpr(getASTContext()); 2115*2c75bda4Serichkeane 2116*2c75bda4Serichkeane // OpenACC 3.3: 2.9.1 2117*2c75bda4Serichkeane // The argument to the collapse clause must be a constant positive integer 2118*2c75bda4Serichkeane // expression. 2119*2c75bda4Serichkeane if (!ICE || *ICE <= 0) { 2120*2c75bda4Serichkeane Diag(LoopCount->getBeginLoc(), diag::err_acc_collapse_loop_count) 2121*2c75bda4Serichkeane << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue(); 2122*2c75bda4Serichkeane return ExprError(); 2123*2c75bda4Serichkeane } 2124*2c75bda4Serichkeane 2125*2c75bda4Serichkeane return ExprResult{ 2126*2c75bda4Serichkeane ConstantExpr::Create(getASTContext(), LoopCount, APValue{*ICE})}; 2127*2c75bda4Serichkeane } 2128*2c75bda4Serichkeane 2129*2c75bda4Serichkeane ExprResult 2130*2c75bda4Serichkeane SemaOpenACC::CheckGangExpr(ArrayRef<const OpenACCClause *> ExistingClauses, 2131*2c75bda4Serichkeane OpenACCDirectiveKind DK, OpenACCGangKind GK, 2132*2c75bda4Serichkeane Expr *E) { 2133*2c75bda4Serichkeane // There are two cases for the enforcement here: the 'current' directive is a 2134*2c75bda4Serichkeane // 'loop', where we need to check the active compute construct kind, or the 2135*2c75bda4Serichkeane // current directive is a 'combined' construct, where we have to check the 2136*2c75bda4Serichkeane // current one. 2137*2c75bda4Serichkeane switch (DK) { 2138*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 2139*2c75bda4Serichkeane return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK, 2140*2c75bda4Serichkeane E); 2141*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 2142*2c75bda4Serichkeane return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK, 2143*2c75bda4Serichkeane E); 2144*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 2145*2c75bda4Serichkeane return CheckGangKernelsExpr(*this, ExistingClauses, DK, 2146*2c75bda4Serichkeane ActiveComputeConstructInfo.Kind, GK, E); 2147*2c75bda4Serichkeane case OpenACCDirectiveKind::Loop: 2148*2c75bda4Serichkeane switch (ActiveComputeConstructInfo.Kind) { 2149*2c75bda4Serichkeane case OpenACCDirectiveKind::Invalid: 2150*2c75bda4Serichkeane case OpenACCDirectiveKind::Parallel: 2151*2c75bda4Serichkeane case OpenACCDirectiveKind::ParallelLoop: 2152*2c75bda4Serichkeane return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, 2153*2c75bda4Serichkeane GK, E); 2154*2c75bda4Serichkeane case OpenACCDirectiveKind::SerialLoop: 2155*2c75bda4Serichkeane case OpenACCDirectiveKind::Serial: 2156*2c75bda4Serichkeane return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK, 2157*2c75bda4Serichkeane E); 2158*2c75bda4Serichkeane case OpenACCDirectiveKind::KernelsLoop: 2159*2c75bda4Serichkeane case OpenACCDirectiveKind::Kernels: 2160*2c75bda4Serichkeane return CheckGangKernelsExpr(*this, ExistingClauses, DK, 2161*2c75bda4Serichkeane ActiveComputeConstructInfo.Kind, GK, E); 2162*2c75bda4Serichkeane default: 2163*2c75bda4Serichkeane llvm_unreachable("Non compute construct in active compute construct?"); 2164*2c75bda4Serichkeane } 2165*2c75bda4Serichkeane default: 2166*2c75bda4Serichkeane // TODO: OpenACC: when we implement this on 'routine', we'll have to 2167*2c75bda4Serichkeane // implement its checking here. 2168*2c75bda4Serichkeane llvm_unreachable("Invalid directive kind for a Gang clause"); 2169*2c75bda4Serichkeane } 2170*2c75bda4Serichkeane llvm_unreachable("Compute construct directive not handled?"); 2171*2c75bda4Serichkeane } 2172*2c75bda4Serichkeane 2173*2c75bda4Serichkeane OpenACCClause * 2174*2c75bda4Serichkeane SemaOpenACC::CheckGangClause(OpenACCDirectiveKind DirKind, 2175*2c75bda4Serichkeane ArrayRef<const OpenACCClause *> ExistingClauses, 2176*2c75bda4Serichkeane SourceLocation BeginLoc, SourceLocation LParenLoc, 2177*2c75bda4Serichkeane ArrayRef<OpenACCGangKind> GangKinds, 2178*2c75bda4Serichkeane ArrayRef<Expr *> IntExprs, SourceLocation EndLoc) { 2179*2c75bda4Serichkeane // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive 2180*2c75bda4Serichkeane // that has a gang clause with a dim: argument whose value is greater than 1. 2181*2c75bda4Serichkeane 2182*2c75bda4Serichkeane const auto *ReductionItr = 2183*2c75bda4Serichkeane llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>); 2184*2c75bda4Serichkeane 2185*2c75bda4Serichkeane if (ReductionItr != ExistingClauses.end()) { 2186*2c75bda4Serichkeane const auto GangZip = llvm::zip_equal(GangKinds, IntExprs); 2187*2c75bda4Serichkeane const auto GangItr = llvm::find_if(GangZip, [](const auto &Tuple) { 2188*2c75bda4Serichkeane return std::get<0>(Tuple) == OpenACCGangKind::Dim; 2189*2c75bda4Serichkeane }); 2190*2c75bda4Serichkeane 2191*2c75bda4Serichkeane if (GangItr != GangZip.end()) { 2192*2c75bda4Serichkeane const Expr *DimExpr = std::get<1>(*GangItr); 2193*2c75bda4Serichkeane 2194*2c75bda4Serichkeane assert( 2195*2c75bda4Serichkeane (DimExpr->isInstantiationDependent() || isa<ConstantExpr>(DimExpr)) && 2196*2c75bda4Serichkeane "Improperly formed gang argument"); 2197*2c75bda4Serichkeane if (const auto *DimVal = dyn_cast<ConstantExpr>(DimExpr); 2198*2c75bda4Serichkeane DimVal && DimVal->getResultAsAPSInt() > 1) { 2199*2c75bda4Serichkeane Diag(DimVal->getBeginLoc(), diag::err_acc_gang_reduction_conflict) 2200*2c75bda4Serichkeane << /*gang/reduction=*/0 << DirKind; 2201*2c75bda4Serichkeane Diag((*ReductionItr)->getBeginLoc(), 2202*2c75bda4Serichkeane diag::note_acc_previous_clause_here); 2203*2c75bda4Serichkeane return nullptr; 2204*2c75bda4Serichkeane } 2205*2c75bda4Serichkeane } 2206*2c75bda4Serichkeane } 2207*2c75bda4Serichkeane 2208*2c75bda4Serichkeane return OpenACCGangClause::Create(getASTContext(), BeginLoc, LParenLoc, 2209*2c75bda4Serichkeane GangKinds, IntExprs, EndLoc); 2210*2c75bda4Serichkeane } 2211*2c75bda4Serichkeane 2212*2c75bda4Serichkeane OpenACCClause *SemaOpenACC::CheckReductionClause( 2213*2c75bda4Serichkeane ArrayRef<const OpenACCClause *> ExistingClauses, 2214*2c75bda4Serichkeane OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc, 2215*2c75bda4Serichkeane SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp, 2216*2c75bda4Serichkeane ArrayRef<Expr *> Vars, SourceLocation EndLoc) { 2217*2c75bda4Serichkeane if (DirectiveKind == OpenACCDirectiveKind::Loop || 2218*2c75bda4Serichkeane isOpenACCCombinedDirectiveKind(DirectiveKind)) { 2219*2c75bda4Serichkeane // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive 2220*2c75bda4Serichkeane // that has a gang clause with a dim: argument whose value is greater 2221*2c75bda4Serichkeane // than 1. 2222*2c75bda4Serichkeane const auto GangClauses = llvm::make_filter_range( 2223*2c75bda4Serichkeane ExistingClauses, llvm::IsaPred<OpenACCGangClause>); 2224*2c75bda4Serichkeane 2225*2c75bda4Serichkeane for (auto *GC : GangClauses) { 2226*2c75bda4Serichkeane const auto *GangClause = cast<OpenACCGangClause>(GC); 2227*2c75bda4Serichkeane for (unsigned I = 0; I < GangClause->getNumExprs(); ++I) { 2228*2c75bda4Serichkeane std::pair<OpenACCGangKind, const Expr *> EPair = GangClause->getExpr(I); 2229*2c75bda4Serichkeane if (EPair.first != OpenACCGangKind::Dim) 2230*2c75bda4Serichkeane continue; 2231*2c75bda4Serichkeane 2232*2c75bda4Serichkeane if (const auto *DimVal = dyn_cast<ConstantExpr>(EPair.second); 2233*2c75bda4Serichkeane DimVal && DimVal->getResultAsAPSInt() > 1) { 2234*2c75bda4Serichkeane Diag(BeginLoc, diag::err_acc_gang_reduction_conflict) 2235*2c75bda4Serichkeane << /*reduction/gang=*/1 << DirectiveKind; 2236*2c75bda4Serichkeane Diag(GangClause->getBeginLoc(), diag::note_acc_previous_clause_here); 2237*2c75bda4Serichkeane return nullptr; 2238*2c75bda4Serichkeane } 2239*2c75bda4Serichkeane } 2240*2c75bda4Serichkeane } 2241*2c75bda4Serichkeane } 2242*2c75bda4Serichkeane 2243*2c75bda4Serichkeane auto *Ret = OpenACCReductionClause::Create( 2244*2c75bda4Serichkeane getASTContext(), BeginLoc, LParenLoc, ReductionOp, Vars, EndLoc); 2245*2c75bda4Serichkeane return Ret; 2246*2c75bda4Serichkeane } 2247