1*0fca6ea1SDimitry Andric //===--- SemaOpenACC.cpp - Semantic Analysis for OpenACC constructs -------===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric /// \file 9*0fca6ea1SDimitry Andric /// This file implements semantic analysis for OpenACC constructs and 10*0fca6ea1SDimitry Andric /// clauses. 11*0fca6ea1SDimitry Andric /// 12*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 13*0fca6ea1SDimitry Andric 14*0fca6ea1SDimitry Andric #include "clang/Sema/SemaOpenACC.h" 15*0fca6ea1SDimitry Andric #include "clang/AST/StmtOpenACC.h" 16*0fca6ea1SDimitry Andric #include "clang/Basic/DiagnosticSema.h" 17*0fca6ea1SDimitry Andric #include "clang/Basic/OpenACCKinds.h" 18*0fca6ea1SDimitry Andric #include "clang/Sema/Sema.h" 19*0fca6ea1SDimitry Andric #include "llvm/ADT/StringExtras.h" 20*0fca6ea1SDimitry Andric #include "llvm/Support/Casting.h" 21*0fca6ea1SDimitry Andric 22*0fca6ea1SDimitry Andric using namespace clang; 23*0fca6ea1SDimitry Andric 24*0fca6ea1SDimitry Andric namespace { 25*0fca6ea1SDimitry Andric bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K, 26*0fca6ea1SDimitry Andric SourceLocation StartLoc, bool IsStmt) { 27*0fca6ea1SDimitry Andric switch (K) { 28*0fca6ea1SDimitry Andric default: 29*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Invalid: 30*0fca6ea1SDimitry Andric // Nothing to do here, both invalid and unimplemented don't really need to 31*0fca6ea1SDimitry Andric // do anything. 32*0fca6ea1SDimitry Andric break; 33*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 34*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 35*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 36*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Loop: 37*0fca6ea1SDimitry Andric if (!IsStmt) 38*0fca6ea1SDimitry Andric return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K; 39*0fca6ea1SDimitry Andric break; 40*0fca6ea1SDimitry Andric } 41*0fca6ea1SDimitry Andric return false; 42*0fca6ea1SDimitry Andric } 43*0fca6ea1SDimitry Andric 44*0fca6ea1SDimitry Andric bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind, 45*0fca6ea1SDimitry Andric OpenACCClauseKind ClauseKind) { 46*0fca6ea1SDimitry Andric switch (ClauseKind) { 47*0fca6ea1SDimitry Andric // FIXME: For each clause as we implement them, we can add the 48*0fca6ea1SDimitry Andric // 'legalization' list here. 49*0fca6ea1SDimitry Andric case OpenACCClauseKind::Default: 50*0fca6ea1SDimitry Andric switch (DirectiveKind) { 51*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 52*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 53*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 54*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 55*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 56*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 57*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 58*0fca6ea1SDimitry Andric return true; 59*0fca6ea1SDimitry Andric default: 60*0fca6ea1SDimitry Andric return false; 61*0fca6ea1SDimitry Andric } 62*0fca6ea1SDimitry Andric case OpenACCClauseKind::If: 63*0fca6ea1SDimitry Andric switch (DirectiveKind) { 64*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 65*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 66*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 67*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 68*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::EnterData: 69*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ExitData: 70*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::HostData: 71*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Init: 72*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Shutdown: 73*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Set: 74*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Update: 75*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Wait: 76*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 77*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 78*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 79*0fca6ea1SDimitry Andric return true; 80*0fca6ea1SDimitry Andric default: 81*0fca6ea1SDimitry Andric return false; 82*0fca6ea1SDimitry Andric } 83*0fca6ea1SDimitry Andric case OpenACCClauseKind::Self: 84*0fca6ea1SDimitry Andric switch (DirectiveKind) { 85*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 86*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 87*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 88*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Update: 89*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 90*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 91*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 92*0fca6ea1SDimitry Andric return true; 93*0fca6ea1SDimitry Andric default: 94*0fca6ea1SDimitry Andric return false; 95*0fca6ea1SDimitry Andric } 96*0fca6ea1SDimitry Andric case OpenACCClauseKind::NumGangs: 97*0fca6ea1SDimitry Andric case OpenACCClauseKind::NumWorkers: 98*0fca6ea1SDimitry Andric case OpenACCClauseKind::VectorLength: 99*0fca6ea1SDimitry Andric switch (DirectiveKind) { 100*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 101*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 102*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 103*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 104*0fca6ea1SDimitry Andric return true; 105*0fca6ea1SDimitry Andric default: 106*0fca6ea1SDimitry Andric return false; 107*0fca6ea1SDimitry Andric } 108*0fca6ea1SDimitry Andric case OpenACCClauseKind::FirstPrivate: 109*0fca6ea1SDimitry Andric switch (DirectiveKind) { 110*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 111*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 112*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 113*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 114*0fca6ea1SDimitry Andric return true; 115*0fca6ea1SDimitry Andric default: 116*0fca6ea1SDimitry Andric return false; 117*0fca6ea1SDimitry Andric } 118*0fca6ea1SDimitry Andric case OpenACCClauseKind::Private: 119*0fca6ea1SDimitry Andric switch (DirectiveKind) { 120*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 121*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 122*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Loop: 123*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 124*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 125*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 126*0fca6ea1SDimitry Andric return true; 127*0fca6ea1SDimitry Andric default: 128*0fca6ea1SDimitry Andric return false; 129*0fca6ea1SDimitry Andric } 130*0fca6ea1SDimitry Andric case OpenACCClauseKind::NoCreate: 131*0fca6ea1SDimitry Andric switch (DirectiveKind) { 132*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 133*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 134*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 135*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 136*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 137*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 138*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 139*0fca6ea1SDimitry Andric return true; 140*0fca6ea1SDimitry Andric default: 141*0fca6ea1SDimitry Andric return false; 142*0fca6ea1SDimitry Andric } 143*0fca6ea1SDimitry Andric case OpenACCClauseKind::Present: 144*0fca6ea1SDimitry Andric switch (DirectiveKind) { 145*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 146*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 147*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 148*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 149*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Declare: 150*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 151*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 152*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 153*0fca6ea1SDimitry Andric return true; 154*0fca6ea1SDimitry Andric default: 155*0fca6ea1SDimitry Andric return false; 156*0fca6ea1SDimitry Andric } 157*0fca6ea1SDimitry Andric 158*0fca6ea1SDimitry Andric case OpenACCClauseKind::Copy: 159*0fca6ea1SDimitry Andric case OpenACCClauseKind::PCopy: 160*0fca6ea1SDimitry Andric case OpenACCClauseKind::PresentOrCopy: 161*0fca6ea1SDimitry Andric switch (DirectiveKind) { 162*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 163*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 164*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 165*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 166*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Declare: 167*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 168*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 169*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 170*0fca6ea1SDimitry Andric return true; 171*0fca6ea1SDimitry Andric default: 172*0fca6ea1SDimitry Andric return false; 173*0fca6ea1SDimitry Andric } 174*0fca6ea1SDimitry Andric case OpenACCClauseKind::CopyIn: 175*0fca6ea1SDimitry Andric case OpenACCClauseKind::PCopyIn: 176*0fca6ea1SDimitry Andric case OpenACCClauseKind::PresentOrCopyIn: 177*0fca6ea1SDimitry Andric switch (DirectiveKind) { 178*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 179*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 180*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 181*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 182*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::EnterData: 183*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Declare: 184*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 185*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 186*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 187*0fca6ea1SDimitry Andric return true; 188*0fca6ea1SDimitry Andric default: 189*0fca6ea1SDimitry Andric return false; 190*0fca6ea1SDimitry Andric } 191*0fca6ea1SDimitry Andric case OpenACCClauseKind::CopyOut: 192*0fca6ea1SDimitry Andric case OpenACCClauseKind::PCopyOut: 193*0fca6ea1SDimitry Andric case OpenACCClauseKind::PresentOrCopyOut: 194*0fca6ea1SDimitry Andric switch (DirectiveKind) { 195*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 196*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 197*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 198*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 199*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ExitData: 200*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Declare: 201*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 202*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 203*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 204*0fca6ea1SDimitry Andric return true; 205*0fca6ea1SDimitry Andric default: 206*0fca6ea1SDimitry Andric return false; 207*0fca6ea1SDimitry Andric } 208*0fca6ea1SDimitry Andric case OpenACCClauseKind::Create: 209*0fca6ea1SDimitry Andric case OpenACCClauseKind::PCreate: 210*0fca6ea1SDimitry Andric case OpenACCClauseKind::PresentOrCreate: 211*0fca6ea1SDimitry Andric switch (DirectiveKind) { 212*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 213*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 214*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 215*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 216*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::EnterData: 217*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 218*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 219*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 220*0fca6ea1SDimitry Andric return true; 221*0fca6ea1SDimitry Andric default: 222*0fca6ea1SDimitry Andric return false; 223*0fca6ea1SDimitry Andric } 224*0fca6ea1SDimitry Andric 225*0fca6ea1SDimitry Andric case OpenACCClauseKind::Attach: 226*0fca6ea1SDimitry Andric switch (DirectiveKind) { 227*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 228*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 229*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 230*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 231*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::EnterData: 232*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 233*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 234*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 235*0fca6ea1SDimitry Andric return true; 236*0fca6ea1SDimitry Andric default: 237*0fca6ea1SDimitry Andric return false; 238*0fca6ea1SDimitry Andric } 239*0fca6ea1SDimitry Andric case OpenACCClauseKind::DevicePtr: 240*0fca6ea1SDimitry Andric switch (DirectiveKind) { 241*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 242*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 243*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 244*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 245*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Declare: 246*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 247*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 248*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 249*0fca6ea1SDimitry Andric return true; 250*0fca6ea1SDimitry Andric default: 251*0fca6ea1SDimitry Andric return false; 252*0fca6ea1SDimitry Andric } 253*0fca6ea1SDimitry Andric case OpenACCClauseKind::Async: 254*0fca6ea1SDimitry Andric switch (DirectiveKind) { 255*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 256*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 257*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 258*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 259*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::EnterData: 260*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ExitData: 261*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Set: 262*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Update: 263*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Wait: 264*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 265*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 266*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 267*0fca6ea1SDimitry Andric return true; 268*0fca6ea1SDimitry Andric default: 269*0fca6ea1SDimitry Andric return false; 270*0fca6ea1SDimitry Andric } 271*0fca6ea1SDimitry Andric case OpenACCClauseKind::Wait: 272*0fca6ea1SDimitry Andric switch (DirectiveKind) { 273*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 274*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 275*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 276*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 277*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::EnterData: 278*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ExitData: 279*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Update: 280*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 281*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 282*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 283*0fca6ea1SDimitry Andric return true; 284*0fca6ea1SDimitry Andric default: 285*0fca6ea1SDimitry Andric return false; 286*0fca6ea1SDimitry Andric } 287*0fca6ea1SDimitry Andric 288*0fca6ea1SDimitry Andric case OpenACCClauseKind::Seq: 289*0fca6ea1SDimitry Andric switch (DirectiveKind) { 290*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Loop: 291*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Routine: 292*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 293*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 294*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 295*0fca6ea1SDimitry Andric return true; 296*0fca6ea1SDimitry Andric default: 297*0fca6ea1SDimitry Andric return false; 298*0fca6ea1SDimitry Andric } 299*0fca6ea1SDimitry Andric 300*0fca6ea1SDimitry Andric case OpenACCClauseKind::Independent: 301*0fca6ea1SDimitry Andric case OpenACCClauseKind::Auto: 302*0fca6ea1SDimitry Andric switch (DirectiveKind) { 303*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Loop: 304*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 305*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 306*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 307*0fca6ea1SDimitry Andric return true; 308*0fca6ea1SDimitry Andric default: 309*0fca6ea1SDimitry Andric return false; 310*0fca6ea1SDimitry Andric } 311*0fca6ea1SDimitry Andric 312*0fca6ea1SDimitry Andric case OpenACCClauseKind::Reduction: 313*0fca6ea1SDimitry Andric switch (DirectiveKind) { 314*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 315*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 316*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Loop: 317*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 318*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 319*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 320*0fca6ea1SDimitry Andric return true; 321*0fca6ea1SDimitry Andric default: 322*0fca6ea1SDimitry Andric return false; 323*0fca6ea1SDimitry Andric } 324*0fca6ea1SDimitry Andric 325*0fca6ea1SDimitry Andric case OpenACCClauseKind::DeviceType: 326*0fca6ea1SDimitry Andric case OpenACCClauseKind::DType: 327*0fca6ea1SDimitry Andric switch (DirectiveKind) { 328*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 329*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 330*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 331*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Data: 332*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Init: 333*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Shutdown: 334*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Set: 335*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Update: 336*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Loop: 337*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Routine: 338*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::ParallelLoop: 339*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::SerialLoop: 340*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::KernelsLoop: 341*0fca6ea1SDimitry Andric return true; 342*0fca6ea1SDimitry Andric default: 343*0fca6ea1SDimitry Andric return false; 344*0fca6ea1SDimitry Andric } 345*0fca6ea1SDimitry Andric 346*0fca6ea1SDimitry Andric default: 347*0fca6ea1SDimitry Andric // Do nothing so we can go to the 'unimplemented' diagnostic instead. 348*0fca6ea1SDimitry Andric return true; 349*0fca6ea1SDimitry Andric } 350*0fca6ea1SDimitry Andric llvm_unreachable("Invalid clause kind"); 351*0fca6ea1SDimitry Andric } 352*0fca6ea1SDimitry Andric 353*0fca6ea1SDimitry Andric bool checkAlreadyHasClauseOfKind( 354*0fca6ea1SDimitry Andric SemaOpenACC &S, ArrayRef<const OpenACCClause *> ExistingClauses, 355*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 356*0fca6ea1SDimitry Andric const auto *Itr = llvm::find_if(ExistingClauses, [&](const OpenACCClause *C) { 357*0fca6ea1SDimitry Andric return C->getClauseKind() == Clause.getClauseKind(); 358*0fca6ea1SDimitry Andric }); 359*0fca6ea1SDimitry Andric if (Itr != ExistingClauses.end()) { 360*0fca6ea1SDimitry Andric S.Diag(Clause.getBeginLoc(), diag::err_acc_duplicate_clause_disallowed) 361*0fca6ea1SDimitry Andric << Clause.getDirectiveKind() << Clause.getClauseKind(); 362*0fca6ea1SDimitry Andric S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 363*0fca6ea1SDimitry Andric return true; 364*0fca6ea1SDimitry Andric } 365*0fca6ea1SDimitry Andric return false; 366*0fca6ea1SDimitry Andric } 367*0fca6ea1SDimitry Andric 368*0fca6ea1SDimitry Andric bool checkValidAfterDeviceType( 369*0fca6ea1SDimitry Andric SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause, 370*0fca6ea1SDimitry Andric const SemaOpenACC::OpenACCParsedClause &NewClause) { 371*0fca6ea1SDimitry Andric // This is only a requirement on compute and loop constructs so far, so this 372*0fca6ea1SDimitry Andric // is fine otherwise. 373*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind()) && 374*0fca6ea1SDimitry Andric NewClause.getDirectiveKind() != OpenACCDirectiveKind::Loop) 375*0fca6ea1SDimitry Andric return false; 376*0fca6ea1SDimitry Andric 377*0fca6ea1SDimitry Andric // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are 378*0fca6ea1SDimitry Andric // default clauses. Clauses that follow a device_type clause up to the end of 379*0fca6ea1SDimitry Andric // the directive or up to the next device_type clause are device-specific 380*0fca6ea1SDimitry Andric // clauses for the device types specified in the device_type argument. 381*0fca6ea1SDimitry Andric // 382*0fca6ea1SDimitry Andric // The above implies that despite what the individual text says, these are 383*0fca6ea1SDimitry Andric // valid. 384*0fca6ea1SDimitry Andric if (NewClause.getClauseKind() == OpenACCClauseKind::DType || 385*0fca6ea1SDimitry Andric NewClause.getClauseKind() == OpenACCClauseKind::DeviceType) 386*0fca6ea1SDimitry Andric return false; 387*0fca6ea1SDimitry Andric 388*0fca6ea1SDimitry Andric // Implement check from OpenACC3.3: section 2.5.4: 389*0fca6ea1SDimitry Andric // Only the async, wait, num_gangs, num_workers, and vector_length clauses may 390*0fca6ea1SDimitry Andric // follow a device_type clause. 391*0fca6ea1SDimitry Andric if (isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind())) { 392*0fca6ea1SDimitry Andric switch (NewClause.getClauseKind()) { 393*0fca6ea1SDimitry Andric case OpenACCClauseKind::Async: 394*0fca6ea1SDimitry Andric case OpenACCClauseKind::Wait: 395*0fca6ea1SDimitry Andric case OpenACCClauseKind::NumGangs: 396*0fca6ea1SDimitry Andric case OpenACCClauseKind::NumWorkers: 397*0fca6ea1SDimitry Andric case OpenACCClauseKind::VectorLength: 398*0fca6ea1SDimitry Andric return false; 399*0fca6ea1SDimitry Andric default: 400*0fca6ea1SDimitry Andric break; 401*0fca6ea1SDimitry Andric } 402*0fca6ea1SDimitry Andric } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Loop) { 403*0fca6ea1SDimitry Andric // Implement check from OpenACC3.3: section 2.9: 404*0fca6ea1SDimitry Andric // Only the collapse, gang, worker, vector, seq, independent, auto, and tile 405*0fca6ea1SDimitry Andric // clauses may follow a device_type clause. 406*0fca6ea1SDimitry Andric switch (NewClause.getClauseKind()) { 407*0fca6ea1SDimitry Andric case OpenACCClauseKind::Collapse: 408*0fca6ea1SDimitry Andric case OpenACCClauseKind::Gang: 409*0fca6ea1SDimitry Andric case OpenACCClauseKind::Worker: 410*0fca6ea1SDimitry Andric case OpenACCClauseKind::Vector: 411*0fca6ea1SDimitry Andric case OpenACCClauseKind::Seq: 412*0fca6ea1SDimitry Andric case OpenACCClauseKind::Independent: 413*0fca6ea1SDimitry Andric case OpenACCClauseKind::Auto: 414*0fca6ea1SDimitry Andric case OpenACCClauseKind::Tile: 415*0fca6ea1SDimitry Andric return false; 416*0fca6ea1SDimitry Andric default: 417*0fca6ea1SDimitry Andric break; 418*0fca6ea1SDimitry Andric } 419*0fca6ea1SDimitry Andric } 420*0fca6ea1SDimitry Andric S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type) 421*0fca6ea1SDimitry Andric << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind() 422*0fca6ea1SDimitry Andric << isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind()) 423*0fca6ea1SDimitry Andric << NewClause.getDirectiveKind(); 424*0fca6ea1SDimitry Andric S.Diag(DeviceTypeClause.getBeginLoc(), diag::note_acc_previous_clause_here); 425*0fca6ea1SDimitry Andric return true; 426*0fca6ea1SDimitry Andric } 427*0fca6ea1SDimitry Andric 428*0fca6ea1SDimitry Andric class SemaOpenACCClauseVisitor { 429*0fca6ea1SDimitry Andric SemaOpenACC &SemaRef; 430*0fca6ea1SDimitry Andric ASTContext &Ctx; 431*0fca6ea1SDimitry Andric ArrayRef<const OpenACCClause *> ExistingClauses; 432*0fca6ea1SDimitry Andric bool NotImplemented = false; 433*0fca6ea1SDimitry Andric 434*0fca6ea1SDimitry Andric OpenACCClause *isNotImplemented() { 435*0fca6ea1SDimitry Andric NotImplemented = true; 436*0fca6ea1SDimitry Andric return nullptr; 437*0fca6ea1SDimitry Andric } 438*0fca6ea1SDimitry Andric 439*0fca6ea1SDimitry Andric public: 440*0fca6ea1SDimitry Andric SemaOpenACCClauseVisitor(SemaOpenACC &S, 441*0fca6ea1SDimitry Andric ArrayRef<const OpenACCClause *> ExistingClauses) 442*0fca6ea1SDimitry Andric : SemaRef(S), Ctx(S.getASTContext()), ExistingClauses(ExistingClauses) {} 443*0fca6ea1SDimitry Andric // Once we've implemented everything, we shouldn't need this infrastructure. 444*0fca6ea1SDimitry Andric // But in the meantime, we use this to help decide whether the clause was 445*0fca6ea1SDimitry Andric // handled for this directive. 446*0fca6ea1SDimitry Andric bool diagNotImplemented() { return NotImplemented; } 447*0fca6ea1SDimitry Andric 448*0fca6ea1SDimitry Andric OpenACCClause *Visit(SemaOpenACC::OpenACCParsedClause &Clause) { 449*0fca6ea1SDimitry Andric switch (Clause.getClauseKind()) { 450*0fca6ea1SDimitry Andric case OpenACCClauseKind::Gang: 451*0fca6ea1SDimitry Andric case OpenACCClauseKind::Worker: 452*0fca6ea1SDimitry Andric case OpenACCClauseKind::Vector: { 453*0fca6ea1SDimitry Andric // TODO OpenACC: These are only implemented enough for the 'seq' diagnostic, 454*0fca6ea1SDimitry Andric // otherwise treats itself as unimplemented. When we implement these, we 455*0fca6ea1SDimitry Andric // can remove them from here. 456*0fca6ea1SDimitry Andric 457*0fca6ea1SDimitry Andric // OpenACC 3.3 2.9: 458*0fca6ea1SDimitry Andric // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause 459*0fca6ea1SDimitry Andric // appears. 460*0fca6ea1SDimitry Andric const auto *Itr = 461*0fca6ea1SDimitry Andric llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>); 462*0fca6ea1SDimitry Andric 463*0fca6ea1SDimitry Andric if (Itr != ExistingClauses.end()) { 464*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine) 465*0fca6ea1SDimitry Andric << Clause.getClauseKind() << (*Itr)->getClauseKind(); 466*0fca6ea1SDimitry Andric SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 467*0fca6ea1SDimitry Andric } 468*0fca6ea1SDimitry Andric return isNotImplemented(); 469*0fca6ea1SDimitry Andric } 470*0fca6ea1SDimitry Andric 471*0fca6ea1SDimitry Andric #define VISIT_CLAUSE(CLAUSE_NAME) \ 472*0fca6ea1SDimitry Andric case OpenACCClauseKind::CLAUSE_NAME: \ 473*0fca6ea1SDimitry Andric return Visit##CLAUSE_NAME##Clause(Clause); 474*0fca6ea1SDimitry Andric #define CLAUSE_ALIAS(ALIAS, CLAUSE_NAME, DEPRECATED) \ 475*0fca6ea1SDimitry Andric case OpenACCClauseKind::ALIAS: \ 476*0fca6ea1SDimitry Andric if (DEPRECATED) \ 477*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) \ 478*0fca6ea1SDimitry Andric << Clause.getClauseKind() << OpenACCClauseKind::CLAUSE_NAME; \ 479*0fca6ea1SDimitry Andric return Visit##CLAUSE_NAME##Clause(Clause); 480*0fca6ea1SDimitry Andric #include "clang/Basic/OpenACCClauses.def" 481*0fca6ea1SDimitry Andric default: 482*0fca6ea1SDimitry Andric return isNotImplemented(); 483*0fca6ea1SDimitry Andric } 484*0fca6ea1SDimitry Andric llvm_unreachable("Invalid clause kind"); 485*0fca6ea1SDimitry Andric } 486*0fca6ea1SDimitry Andric 487*0fca6ea1SDimitry Andric #define VISIT_CLAUSE(CLAUSE_NAME) \ 488*0fca6ea1SDimitry Andric OpenACCClause *Visit##CLAUSE_NAME##Clause( \ 489*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause); 490*0fca6ea1SDimitry Andric #include "clang/Basic/OpenACCClauses.def" 491*0fca6ea1SDimitry Andric }; 492*0fca6ea1SDimitry Andric 493*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause( 494*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 495*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 496*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 497*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 498*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 499*0fca6ea1SDimitry Andric return isNotImplemented(); 500*0fca6ea1SDimitry Andric 501*0fca6ea1SDimitry Andric // Don't add an invalid clause to the AST. 502*0fca6ea1SDimitry Andric if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid) 503*0fca6ea1SDimitry Andric return nullptr; 504*0fca6ea1SDimitry Andric 505*0fca6ea1SDimitry Andric // OpenACC 3.3, Section 2.5.4: 506*0fca6ea1SDimitry Andric // At most one 'default' clause may appear, and it must have a value of 507*0fca6ea1SDimitry Andric // either 'none' or 'present'. 508*0fca6ea1SDimitry Andric // Second half of the sentence is diagnosed during parsing. 509*0fca6ea1SDimitry Andric if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 510*0fca6ea1SDimitry Andric return nullptr; 511*0fca6ea1SDimitry Andric 512*0fca6ea1SDimitry Andric return OpenACCDefaultClause::Create( 513*0fca6ea1SDimitry Andric Ctx, Clause.getDefaultClauseKind(), Clause.getBeginLoc(), 514*0fca6ea1SDimitry Andric Clause.getLParenLoc(), Clause.getEndLoc()); 515*0fca6ea1SDimitry Andric } 516*0fca6ea1SDimitry Andric 517*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause( 518*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 519*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 520*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 521*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 522*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 523*0fca6ea1SDimitry Andric return isNotImplemented(); 524*0fca6ea1SDimitry Andric 525*0fca6ea1SDimitry Andric // There is no prose in the standard that says duplicates aren't allowed, 526*0fca6ea1SDimitry Andric // but this diagnostic is present in other compilers, as well as makes 527*0fca6ea1SDimitry Andric // sense. 528*0fca6ea1SDimitry Andric if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 529*0fca6ea1SDimitry Andric return nullptr; 530*0fca6ea1SDimitry Andric 531*0fca6ea1SDimitry Andric // The parser has ensured that we have a proper condition expr, so there 532*0fca6ea1SDimitry Andric // isn't really much to do here. 533*0fca6ea1SDimitry Andric 534*0fca6ea1SDimitry Andric // If the 'if' clause is true, it makes the 'self' clause have no effect, 535*0fca6ea1SDimitry Andric // diagnose that here. 536*0fca6ea1SDimitry Andric // TODO OpenACC: When we add these two to other constructs, we might not 537*0fca6ea1SDimitry Andric // want to warn on this (for example, 'update'). 538*0fca6ea1SDimitry Andric const auto *Itr = 539*0fca6ea1SDimitry Andric llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSelfClause>); 540*0fca6ea1SDimitry Andric if (Itr != ExistingClauses.end()) { 541*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict); 542*0fca6ea1SDimitry Andric SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 543*0fca6ea1SDimitry Andric } 544*0fca6ea1SDimitry Andric 545*0fca6ea1SDimitry Andric return OpenACCIfClause::Create(Ctx, Clause.getBeginLoc(), 546*0fca6ea1SDimitry Andric Clause.getLParenLoc(), 547*0fca6ea1SDimitry Andric Clause.getConditionExpr(), Clause.getEndLoc()); 548*0fca6ea1SDimitry Andric } 549*0fca6ea1SDimitry Andric 550*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitSelfClause( 551*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 552*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 553*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 554*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 555*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 556*0fca6ea1SDimitry Andric return isNotImplemented(); 557*0fca6ea1SDimitry Andric 558*0fca6ea1SDimitry Andric // TODO OpenACC: When we implement this for 'update', this takes a 559*0fca6ea1SDimitry Andric // 'var-list' instead of a condition expression, so semantics/handling has 560*0fca6ea1SDimitry Andric // to happen differently here. 561*0fca6ea1SDimitry Andric 562*0fca6ea1SDimitry Andric // There is no prose in the standard that says duplicates aren't allowed, 563*0fca6ea1SDimitry Andric // but this diagnostic is present in other compilers, as well as makes 564*0fca6ea1SDimitry Andric // sense. 565*0fca6ea1SDimitry Andric if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 566*0fca6ea1SDimitry Andric return nullptr; 567*0fca6ea1SDimitry Andric 568*0fca6ea1SDimitry Andric // If the 'if' clause is true, it makes the 'self' clause have no effect, 569*0fca6ea1SDimitry Andric // diagnose that here. 570*0fca6ea1SDimitry Andric // TODO OpenACC: When we add these two to other constructs, we might not 571*0fca6ea1SDimitry Andric // want to warn on this (for example, 'update'). 572*0fca6ea1SDimitry Andric const auto *Itr = 573*0fca6ea1SDimitry Andric llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCIfClause>); 574*0fca6ea1SDimitry Andric if (Itr != ExistingClauses.end()) { 575*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), diag::warn_acc_if_self_conflict); 576*0fca6ea1SDimitry Andric SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 577*0fca6ea1SDimitry Andric } 578*0fca6ea1SDimitry Andric return OpenACCSelfClause::Create( 579*0fca6ea1SDimitry Andric Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), 580*0fca6ea1SDimitry Andric Clause.getConditionExpr(), Clause.getEndLoc()); 581*0fca6ea1SDimitry Andric } 582*0fca6ea1SDimitry Andric 583*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause( 584*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 585*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 586*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 587*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 588*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 589*0fca6ea1SDimitry Andric return isNotImplemented(); 590*0fca6ea1SDimitry Andric 591*0fca6ea1SDimitry Andric // There is no prose in the standard that says duplicates aren't allowed, 592*0fca6ea1SDimitry Andric // but this diagnostic is present in other compilers, as well as makes 593*0fca6ea1SDimitry Andric // sense. 594*0fca6ea1SDimitry Andric if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 595*0fca6ea1SDimitry Andric return nullptr; 596*0fca6ea1SDimitry Andric 597*0fca6ea1SDimitry Andric // num_gangs requires at least 1 int expr in all forms. Diagnose here, but 598*0fca6ea1SDimitry Andric // allow us to continue, an empty clause might be useful for future 599*0fca6ea1SDimitry Andric // diagnostics. 600*0fca6ea1SDimitry Andric if (Clause.getIntExprs().empty()) 601*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) 602*0fca6ea1SDimitry Andric << /*NoArgs=*/0; 603*0fca6ea1SDimitry Andric 604*0fca6ea1SDimitry Andric unsigned MaxArgs = 605*0fca6ea1SDimitry Andric (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || 606*0fca6ea1SDimitry Andric Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) 607*0fca6ea1SDimitry Andric ? 3 608*0fca6ea1SDimitry Andric : 1; 609*0fca6ea1SDimitry Andric // The max number of args differs between parallel and other constructs. 610*0fca6ea1SDimitry Andric // Again, allow us to continue for the purposes of future diagnostics. 611*0fca6ea1SDimitry Andric if (Clause.getIntExprs().size() > MaxArgs) 612*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_num_gangs_num_args) 613*0fca6ea1SDimitry Andric << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs 614*0fca6ea1SDimitry Andric << Clause.getIntExprs().size(); 615*0fca6ea1SDimitry Andric 616*0fca6ea1SDimitry Andric // OpenACC 3.3 Section 2.5.4: 617*0fca6ea1SDimitry Andric // A reduction clause may not appear on a parallel construct with a 618*0fca6ea1SDimitry Andric // num_gangs clause that has more than one argument. 619*0fca6ea1SDimitry Andric if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel && 620*0fca6ea1SDimitry Andric Clause.getIntExprs().size() > 1) { 621*0fca6ea1SDimitry Andric auto *Parallel = 622*0fca6ea1SDimitry Andric llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCReductionClause>); 623*0fca6ea1SDimitry Andric 624*0fca6ea1SDimitry Andric if (Parallel != ExistingClauses.end()) { 625*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), 626*0fca6ea1SDimitry Andric diag::err_acc_reduction_num_gangs_conflict) 627*0fca6ea1SDimitry Andric << Clause.getIntExprs().size(); 628*0fca6ea1SDimitry Andric SemaRef.Diag((*Parallel)->getBeginLoc(), 629*0fca6ea1SDimitry Andric diag::note_acc_previous_clause_here); 630*0fca6ea1SDimitry Andric return nullptr; 631*0fca6ea1SDimitry Andric } 632*0fca6ea1SDimitry Andric } 633*0fca6ea1SDimitry Andric return OpenACCNumGangsClause::Create( 634*0fca6ea1SDimitry Andric Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs(), 635*0fca6ea1SDimitry Andric Clause.getEndLoc()); 636*0fca6ea1SDimitry Andric } 637*0fca6ea1SDimitry Andric 638*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause( 639*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 640*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 641*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 642*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 643*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 644*0fca6ea1SDimitry Andric return isNotImplemented(); 645*0fca6ea1SDimitry Andric 646*0fca6ea1SDimitry Andric // There is no prose in the standard that says duplicates aren't allowed, 647*0fca6ea1SDimitry Andric // but this diagnostic is present in other compilers, as well as makes 648*0fca6ea1SDimitry Andric // sense. 649*0fca6ea1SDimitry Andric if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 650*0fca6ea1SDimitry Andric return nullptr; 651*0fca6ea1SDimitry Andric 652*0fca6ea1SDimitry Andric assert(Clause.getIntExprs().size() == 1 && 653*0fca6ea1SDimitry Andric "Invalid number of expressions for NumWorkers"); 654*0fca6ea1SDimitry Andric return OpenACCNumWorkersClause::Create( 655*0fca6ea1SDimitry Andric Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], 656*0fca6ea1SDimitry Andric Clause.getEndLoc()); 657*0fca6ea1SDimitry Andric } 658*0fca6ea1SDimitry Andric 659*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause( 660*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 661*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 662*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 663*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 664*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 665*0fca6ea1SDimitry Andric return isNotImplemented(); 666*0fca6ea1SDimitry Andric 667*0fca6ea1SDimitry Andric // There is no prose in the standard that says duplicates aren't allowed, 668*0fca6ea1SDimitry Andric // but this diagnostic is present in other compilers, as well as makes 669*0fca6ea1SDimitry Andric // sense. 670*0fca6ea1SDimitry Andric if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 671*0fca6ea1SDimitry Andric return nullptr; 672*0fca6ea1SDimitry Andric 673*0fca6ea1SDimitry Andric assert(Clause.getIntExprs().size() == 1 && 674*0fca6ea1SDimitry Andric "Invalid number of expressions for NumWorkers"); 675*0fca6ea1SDimitry Andric return OpenACCVectorLengthClause::Create( 676*0fca6ea1SDimitry Andric Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs()[0], 677*0fca6ea1SDimitry Andric Clause.getEndLoc()); 678*0fca6ea1SDimitry Andric } 679*0fca6ea1SDimitry Andric 680*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause( 681*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 682*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 683*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 684*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 685*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 686*0fca6ea1SDimitry Andric return isNotImplemented(); 687*0fca6ea1SDimitry Andric 688*0fca6ea1SDimitry Andric // There is no prose in the standard that says duplicates aren't allowed, 689*0fca6ea1SDimitry Andric // but this diagnostic is present in other compilers, as well as makes 690*0fca6ea1SDimitry Andric // sense. 691*0fca6ea1SDimitry Andric if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) 692*0fca6ea1SDimitry Andric return nullptr; 693*0fca6ea1SDimitry Andric 694*0fca6ea1SDimitry Andric assert(Clause.getNumIntExprs() < 2 && 695*0fca6ea1SDimitry Andric "Invalid number of expressions for Async"); 696*0fca6ea1SDimitry Andric return OpenACCAsyncClause::Create( 697*0fca6ea1SDimitry Andric Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), 698*0fca6ea1SDimitry Andric Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr, 699*0fca6ea1SDimitry Andric Clause.getEndLoc()); 700*0fca6ea1SDimitry Andric } 701*0fca6ea1SDimitry Andric 702*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitPrivateClause( 703*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 704*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' and 'loop' 705*0fca6ea1SDimitry Andric // constructs, and 'compute'/'loop' constructs are the only construct that 706*0fca6ea1SDimitry Andric // can do anything with this yet, so skip/treat as unimplemented in this 707*0fca6ea1SDimitry Andric // case. 708*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && 709*0fca6ea1SDimitry Andric Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) 710*0fca6ea1SDimitry Andric return isNotImplemented(); 711*0fca6ea1SDimitry Andric 712*0fca6ea1SDimitry Andric // ActOnVar ensured that everything is a valid variable reference, so there 713*0fca6ea1SDimitry Andric // really isn't anything to do here. GCC does some duplicate-finding, though 714*0fca6ea1SDimitry Andric // it isn't apparent in the standard where this is justified. 715*0fca6ea1SDimitry Andric 716*0fca6ea1SDimitry Andric return OpenACCPrivateClause::Create(Ctx, Clause.getBeginLoc(), 717*0fca6ea1SDimitry Andric Clause.getLParenLoc(), 718*0fca6ea1SDimitry Andric Clause.getVarList(), Clause.getEndLoc()); 719*0fca6ea1SDimitry Andric } 720*0fca6ea1SDimitry Andric 721*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause( 722*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 723*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 724*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 725*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 726*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 727*0fca6ea1SDimitry Andric return isNotImplemented(); 728*0fca6ea1SDimitry Andric 729*0fca6ea1SDimitry Andric // ActOnVar ensured that everything is a valid variable reference, so there 730*0fca6ea1SDimitry Andric // really isn't anything to do here. GCC does some duplicate-finding, though 731*0fca6ea1SDimitry Andric // it isn't apparent in the standard where this is justified. 732*0fca6ea1SDimitry Andric 733*0fca6ea1SDimitry Andric return OpenACCFirstPrivateClause::Create( 734*0fca6ea1SDimitry Andric Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), 735*0fca6ea1SDimitry Andric Clause.getEndLoc()); 736*0fca6ea1SDimitry Andric } 737*0fca6ea1SDimitry Andric 738*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause( 739*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 740*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 741*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 742*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 743*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 744*0fca6ea1SDimitry Andric return isNotImplemented(); 745*0fca6ea1SDimitry Andric // ActOnVar ensured that everything is a valid variable reference, so there 746*0fca6ea1SDimitry Andric // really isn't anything to do here. GCC does some duplicate-finding, though 747*0fca6ea1SDimitry Andric // it isn't apparent in the standard where this is justified. 748*0fca6ea1SDimitry Andric 749*0fca6ea1SDimitry Andric return OpenACCNoCreateClause::Create(Ctx, Clause.getBeginLoc(), 750*0fca6ea1SDimitry Andric Clause.getLParenLoc(), 751*0fca6ea1SDimitry Andric Clause.getVarList(), Clause.getEndLoc()); 752*0fca6ea1SDimitry Andric } 753*0fca6ea1SDimitry Andric 754*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause( 755*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 756*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 757*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 758*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 759*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 760*0fca6ea1SDimitry Andric return isNotImplemented(); 761*0fca6ea1SDimitry Andric // ActOnVar ensured that everything is a valid variable reference, so there 762*0fca6ea1SDimitry Andric // really isn't anything to do here. GCC does some duplicate-finding, though 763*0fca6ea1SDimitry Andric // it isn't apparent in the standard where this is justified. 764*0fca6ea1SDimitry Andric 765*0fca6ea1SDimitry Andric return OpenACCPresentClause::Create(Ctx, Clause.getBeginLoc(), 766*0fca6ea1SDimitry Andric Clause.getLParenLoc(), 767*0fca6ea1SDimitry Andric Clause.getVarList(), Clause.getEndLoc()); 768*0fca6ea1SDimitry Andric } 769*0fca6ea1SDimitry Andric 770*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause( 771*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 772*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 773*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 774*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 775*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 776*0fca6ea1SDimitry Andric return isNotImplemented(); 777*0fca6ea1SDimitry Andric // ActOnVar ensured that everything is a valid variable reference, so there 778*0fca6ea1SDimitry Andric // really isn't anything to do here. GCC does some duplicate-finding, though 779*0fca6ea1SDimitry Andric // it isn't apparent in the standard where this is justified. 780*0fca6ea1SDimitry Andric 781*0fca6ea1SDimitry Andric return OpenACCCopyClause::Create( 782*0fca6ea1SDimitry Andric Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 783*0fca6ea1SDimitry Andric Clause.getVarList(), Clause.getEndLoc()); 784*0fca6ea1SDimitry Andric } 785*0fca6ea1SDimitry Andric 786*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause( 787*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 788*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 789*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 790*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 791*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 792*0fca6ea1SDimitry Andric return isNotImplemented(); 793*0fca6ea1SDimitry Andric // ActOnVar ensured that everything is a valid variable reference, so there 794*0fca6ea1SDimitry Andric // really isn't anything to do here. GCC does some duplicate-finding, though 795*0fca6ea1SDimitry Andric // it isn't apparent in the standard where this is justified. 796*0fca6ea1SDimitry Andric 797*0fca6ea1SDimitry Andric return OpenACCCopyInClause::Create( 798*0fca6ea1SDimitry Andric Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 799*0fca6ea1SDimitry Andric Clause.isReadOnly(), Clause.getVarList(), Clause.getEndLoc()); 800*0fca6ea1SDimitry Andric } 801*0fca6ea1SDimitry Andric 802*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause( 803*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 804*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 805*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 806*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 807*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 808*0fca6ea1SDimitry Andric return isNotImplemented(); 809*0fca6ea1SDimitry Andric // ActOnVar ensured that everything is a valid variable reference, so there 810*0fca6ea1SDimitry Andric // really isn't anything to do here. GCC does some duplicate-finding, though 811*0fca6ea1SDimitry Andric // it isn't apparent in the standard where this is justified. 812*0fca6ea1SDimitry Andric 813*0fca6ea1SDimitry Andric return OpenACCCopyOutClause::Create( 814*0fca6ea1SDimitry Andric Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 815*0fca6ea1SDimitry Andric Clause.isZero(), Clause.getVarList(), Clause.getEndLoc()); 816*0fca6ea1SDimitry Andric } 817*0fca6ea1SDimitry Andric 818*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause( 819*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 820*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 821*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 822*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 823*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 824*0fca6ea1SDimitry Andric return isNotImplemented(); 825*0fca6ea1SDimitry Andric // ActOnVar ensured that everything is a valid variable reference, so there 826*0fca6ea1SDimitry Andric // really isn't anything to do here. GCC does some duplicate-finding, though 827*0fca6ea1SDimitry Andric // it isn't apparent in the standard where this is justified. 828*0fca6ea1SDimitry Andric 829*0fca6ea1SDimitry Andric return OpenACCCreateClause::Create( 830*0fca6ea1SDimitry Andric Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 831*0fca6ea1SDimitry Andric Clause.isZero(), Clause.getVarList(), Clause.getEndLoc()); 832*0fca6ea1SDimitry Andric } 833*0fca6ea1SDimitry Andric 834*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause( 835*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 836*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 837*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 838*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 839*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 840*0fca6ea1SDimitry Andric return isNotImplemented(); 841*0fca6ea1SDimitry Andric 842*0fca6ea1SDimitry Andric // ActOnVar ensured that everything is a valid variable reference, but we 843*0fca6ea1SDimitry Andric // still have to make sure it is a pointer type. 844*0fca6ea1SDimitry Andric llvm::SmallVector<Expr *> VarList{Clause.getVarList()}; 845*0fca6ea1SDimitry Andric llvm::erase_if(VarList, [&](Expr *E) { 846*0fca6ea1SDimitry Andric return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Attach, E); 847*0fca6ea1SDimitry Andric }); 848*0fca6ea1SDimitry Andric Clause.setVarListDetails(VarList, 849*0fca6ea1SDimitry Andric /*IsReadOnly=*/false, /*IsZero=*/false); 850*0fca6ea1SDimitry Andric return OpenACCAttachClause::Create(Ctx, Clause.getBeginLoc(), 851*0fca6ea1SDimitry Andric Clause.getLParenLoc(), Clause.getVarList(), 852*0fca6ea1SDimitry Andric Clause.getEndLoc()); 853*0fca6ea1SDimitry Andric } 854*0fca6ea1SDimitry Andric 855*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause( 856*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 857*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 858*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 859*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 860*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 861*0fca6ea1SDimitry Andric return isNotImplemented(); 862*0fca6ea1SDimitry Andric 863*0fca6ea1SDimitry Andric // ActOnVar ensured that everything is a valid variable reference, but we 864*0fca6ea1SDimitry Andric // still have to make sure it is a pointer type. 865*0fca6ea1SDimitry Andric llvm::SmallVector<Expr *> VarList{Clause.getVarList()}; 866*0fca6ea1SDimitry Andric llvm::erase_if(VarList, [&](Expr *E) { 867*0fca6ea1SDimitry Andric return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::DevicePtr, E); 868*0fca6ea1SDimitry Andric }); 869*0fca6ea1SDimitry Andric Clause.setVarListDetails(VarList, 870*0fca6ea1SDimitry Andric /*IsReadOnly=*/false, /*IsZero=*/false); 871*0fca6ea1SDimitry Andric 872*0fca6ea1SDimitry Andric return OpenACCDevicePtrClause::Create( 873*0fca6ea1SDimitry Andric Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), 874*0fca6ea1SDimitry Andric Clause.getEndLoc()); 875*0fca6ea1SDimitry Andric } 876*0fca6ea1SDimitry Andric 877*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause( 878*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 879*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 880*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 881*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 882*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 883*0fca6ea1SDimitry Andric return isNotImplemented(); 884*0fca6ea1SDimitry Andric 885*0fca6ea1SDimitry Andric return OpenACCWaitClause::Create( 886*0fca6ea1SDimitry Andric Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getDevNumExpr(), 887*0fca6ea1SDimitry Andric Clause.getQueuesLoc(), Clause.getQueueIdExprs(), Clause.getEndLoc()); 888*0fca6ea1SDimitry Andric } 889*0fca6ea1SDimitry Andric 890*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause( 891*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 892*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' and 'loop' 893*0fca6ea1SDimitry Andric // constructs, and 'compute'/'loop' constructs are the only construct that 894*0fca6ea1SDimitry Andric // can do anything with this yet, so skip/treat as unimplemented in this 895*0fca6ea1SDimitry Andric // case. 896*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && 897*0fca6ea1SDimitry Andric Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) 898*0fca6ea1SDimitry Andric return isNotImplemented(); 899*0fca6ea1SDimitry Andric 900*0fca6ea1SDimitry Andric // TODO OpenACC: Once we get enough of the CodeGen implemented that we have 901*0fca6ea1SDimitry Andric // a source for the list of valid architectures, we need to warn on unknown 902*0fca6ea1SDimitry Andric // identifiers here. 903*0fca6ea1SDimitry Andric 904*0fca6ea1SDimitry Andric return OpenACCDeviceTypeClause::Create( 905*0fca6ea1SDimitry Andric Ctx, Clause.getClauseKind(), Clause.getBeginLoc(), Clause.getLParenLoc(), 906*0fca6ea1SDimitry Andric Clause.getDeviceTypeArchitectures(), Clause.getEndLoc()); 907*0fca6ea1SDimitry Andric } 908*0fca6ea1SDimitry Andric 909*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitAutoClause( 910*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 911*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'loop' constructs, and it is 912*0fca6ea1SDimitry Andric // the only construct that can do anything with this, so skip/treat as 913*0fca6ea1SDimitry Andric // unimplemented for the combined constructs. 914*0fca6ea1SDimitry Andric if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) 915*0fca6ea1SDimitry Andric return isNotImplemented(); 916*0fca6ea1SDimitry Andric 917*0fca6ea1SDimitry Andric // OpenACC 3.3 2.9: 918*0fca6ea1SDimitry Andric // Only one of the seq, independent, and auto clauses may appear. 919*0fca6ea1SDimitry Andric const auto *Itr = 920*0fca6ea1SDimitry Andric llvm::find_if(ExistingClauses, 921*0fca6ea1SDimitry Andric llvm::IsaPred<OpenACCIndependentClause, OpenACCSeqClause>); 922*0fca6ea1SDimitry Andric if (Itr != ExistingClauses.end()) { 923*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict) 924*0fca6ea1SDimitry Andric << Clause.getClauseKind() << Clause.getDirectiveKind(); 925*0fca6ea1SDimitry Andric SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 926*0fca6ea1SDimitry Andric return nullptr; 927*0fca6ea1SDimitry Andric } 928*0fca6ea1SDimitry Andric 929*0fca6ea1SDimitry Andric return OpenACCAutoClause::Create(Ctx, Clause.getBeginLoc(), 930*0fca6ea1SDimitry Andric Clause.getEndLoc()); 931*0fca6ea1SDimitry Andric } 932*0fca6ea1SDimitry Andric 933*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause( 934*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 935*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'loop' constructs, and it is 936*0fca6ea1SDimitry Andric // the only construct that can do anything with this, so skip/treat as 937*0fca6ea1SDimitry Andric // unimplemented for the combined constructs. 938*0fca6ea1SDimitry Andric if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) 939*0fca6ea1SDimitry Andric return isNotImplemented(); 940*0fca6ea1SDimitry Andric 941*0fca6ea1SDimitry Andric // OpenACC 3.3 2.9: 942*0fca6ea1SDimitry Andric // Only one of the seq, independent, and auto clauses may appear. 943*0fca6ea1SDimitry Andric const auto *Itr = llvm::find_if( 944*0fca6ea1SDimitry Andric ExistingClauses, llvm::IsaPred<OpenACCAutoClause, OpenACCSeqClause>); 945*0fca6ea1SDimitry Andric if (Itr != ExistingClauses.end()) { 946*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict) 947*0fca6ea1SDimitry Andric << Clause.getClauseKind() << Clause.getDirectiveKind(); 948*0fca6ea1SDimitry Andric SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 949*0fca6ea1SDimitry Andric return nullptr; 950*0fca6ea1SDimitry Andric } 951*0fca6ea1SDimitry Andric 952*0fca6ea1SDimitry Andric return OpenACCIndependentClause::Create(Ctx, Clause.getBeginLoc(), 953*0fca6ea1SDimitry Andric Clause.getEndLoc()); 954*0fca6ea1SDimitry Andric } 955*0fca6ea1SDimitry Andric 956*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause( 957*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 958*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'loop' constructs, and it is 959*0fca6ea1SDimitry Andric // the only construct that can do anything with this, so skip/treat as 960*0fca6ea1SDimitry Andric // unimplemented for the combined constructs. 961*0fca6ea1SDimitry Andric if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) 962*0fca6ea1SDimitry Andric return isNotImplemented(); 963*0fca6ea1SDimitry Andric 964*0fca6ea1SDimitry Andric // OpenACC 3.3 2.9: 965*0fca6ea1SDimitry Andric // Only one of the seq, independent, and auto clauses may appear. 966*0fca6ea1SDimitry Andric const auto *Itr = 967*0fca6ea1SDimitry Andric llvm::find_if(ExistingClauses, 968*0fca6ea1SDimitry Andric llvm::IsaPred<OpenACCAutoClause, OpenACCIndependentClause>); 969*0fca6ea1SDimitry Andric if (Itr != ExistingClauses.end()) { 970*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_loop_spec_conflict) 971*0fca6ea1SDimitry Andric << Clause.getClauseKind() << Clause.getDirectiveKind(); 972*0fca6ea1SDimitry Andric SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 973*0fca6ea1SDimitry Andric return nullptr; 974*0fca6ea1SDimitry Andric } 975*0fca6ea1SDimitry Andric 976*0fca6ea1SDimitry Andric // OpenACC 3.3 2.9: 977*0fca6ea1SDimitry Andric // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' clause 978*0fca6ea1SDimitry Andric // appears. 979*0fca6ea1SDimitry Andric Itr = llvm::find_if(ExistingClauses, 980*0fca6ea1SDimitry Andric llvm::IsaPred<OpenACCGangClause, OpenACCWorkerClause, 981*0fca6ea1SDimitry Andric OpenACCVectorClause>); 982*0fca6ea1SDimitry Andric 983*0fca6ea1SDimitry Andric if (Itr != ExistingClauses.end()) { 984*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine) 985*0fca6ea1SDimitry Andric << Clause.getClauseKind() << (*Itr)->getClauseKind(); 986*0fca6ea1SDimitry Andric SemaRef.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 987*0fca6ea1SDimitry Andric return nullptr; 988*0fca6ea1SDimitry Andric } 989*0fca6ea1SDimitry Andric 990*0fca6ea1SDimitry Andric // TODO OpenACC: 2.9 ~ line 2010 specifies that the associated loop has some 991*0fca6ea1SDimitry Andric // restrictions when there is a 'seq' clause in place. We probably need to 992*0fca6ea1SDimitry Andric // implement that. 993*0fca6ea1SDimitry Andric return OpenACCSeqClause::Create(Ctx, Clause.getBeginLoc(), 994*0fca6ea1SDimitry Andric Clause.getEndLoc()); 995*0fca6ea1SDimitry Andric } 996*0fca6ea1SDimitry Andric 997*0fca6ea1SDimitry Andric OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause( 998*0fca6ea1SDimitry Andric SemaOpenACC::OpenACCParsedClause &Clause) { 999*0fca6ea1SDimitry Andric // Restrictions only properly implemented on 'compute' constructs, and 1000*0fca6ea1SDimitry Andric // 'compute' constructs are the only construct that can do anything with 1001*0fca6ea1SDimitry Andric // this yet, so skip/treat as unimplemented in this case. 1002*0fca6ea1SDimitry Andric if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind())) 1003*0fca6ea1SDimitry Andric return isNotImplemented(); 1004*0fca6ea1SDimitry Andric 1005*0fca6ea1SDimitry Andric // OpenACC 3.3 Section 2.5.4: 1006*0fca6ea1SDimitry Andric // A reduction clause may not appear on a parallel construct with a 1007*0fca6ea1SDimitry Andric // num_gangs clause that has more than one argument. 1008*0fca6ea1SDimitry Andric if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel) { 1009*0fca6ea1SDimitry Andric auto NumGangsClauses = llvm::make_filter_range( 1010*0fca6ea1SDimitry Andric ExistingClauses, llvm::IsaPred<OpenACCNumGangsClause>); 1011*0fca6ea1SDimitry Andric 1012*0fca6ea1SDimitry Andric for (auto *NGC : NumGangsClauses) { 1013*0fca6ea1SDimitry Andric unsigned NumExprs = 1014*0fca6ea1SDimitry Andric cast<OpenACCNumGangsClause>(NGC)->getIntExprs().size(); 1015*0fca6ea1SDimitry Andric 1016*0fca6ea1SDimitry Andric if (NumExprs > 1) { 1017*0fca6ea1SDimitry Andric SemaRef.Diag(Clause.getBeginLoc(), 1018*0fca6ea1SDimitry Andric diag::err_acc_reduction_num_gangs_conflict) 1019*0fca6ea1SDimitry Andric << NumExprs; 1020*0fca6ea1SDimitry Andric SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here); 1021*0fca6ea1SDimitry Andric return nullptr; 1022*0fca6ea1SDimitry Andric } 1023*0fca6ea1SDimitry Andric } 1024*0fca6ea1SDimitry Andric } 1025*0fca6ea1SDimitry Andric 1026*0fca6ea1SDimitry Andric SmallVector<Expr *> ValidVars; 1027*0fca6ea1SDimitry Andric 1028*0fca6ea1SDimitry Andric for (Expr *Var : Clause.getVarList()) { 1029*0fca6ea1SDimitry Andric ExprResult Res = SemaRef.CheckReductionVar(Var); 1030*0fca6ea1SDimitry Andric 1031*0fca6ea1SDimitry Andric if (Res.isUsable()) 1032*0fca6ea1SDimitry Andric ValidVars.push_back(Res.get()); 1033*0fca6ea1SDimitry Andric } 1034*0fca6ea1SDimitry Andric 1035*0fca6ea1SDimitry Andric return OpenACCReductionClause::Create( 1036*0fca6ea1SDimitry Andric Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getReductionOp(), 1037*0fca6ea1SDimitry Andric ValidVars, Clause.getEndLoc()); 1038*0fca6ea1SDimitry Andric } 1039*0fca6ea1SDimitry Andric 1040*0fca6ea1SDimitry Andric } // namespace 1041*0fca6ea1SDimitry Andric 1042*0fca6ea1SDimitry Andric SemaOpenACC::SemaOpenACC(Sema &S) : SemaBase(S) {} 1043*0fca6ea1SDimitry Andric 1044*0fca6ea1SDimitry Andric SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII(SemaOpenACC &S, 1045*0fca6ea1SDimitry Andric OpenACCDirectiveKind DK) 1046*0fca6ea1SDimitry Andric : SemaRef(S), WasInsideComputeConstruct(S.InsideComputeConstruct), 1047*0fca6ea1SDimitry Andric DirKind(DK) { 1048*0fca6ea1SDimitry Andric // Compute constructs end up taking their 'loop'. 1049*0fca6ea1SDimitry Andric if (DirKind == OpenACCDirectiveKind::Parallel || 1050*0fca6ea1SDimitry Andric DirKind == OpenACCDirectiveKind::Serial || 1051*0fca6ea1SDimitry Andric DirKind == OpenACCDirectiveKind::Kernels) { 1052*0fca6ea1SDimitry Andric SemaRef.InsideComputeConstruct = true; 1053*0fca6ea1SDimitry Andric SemaRef.ParentlessLoopConstructs.swap(ParentlessLoopConstructs); 1054*0fca6ea1SDimitry Andric } 1055*0fca6ea1SDimitry Andric } 1056*0fca6ea1SDimitry Andric 1057*0fca6ea1SDimitry Andric SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() { 1058*0fca6ea1SDimitry Andric SemaRef.InsideComputeConstruct = WasInsideComputeConstruct; 1059*0fca6ea1SDimitry Andric if (DirKind == OpenACCDirectiveKind::Parallel || 1060*0fca6ea1SDimitry Andric DirKind == OpenACCDirectiveKind::Serial || 1061*0fca6ea1SDimitry Andric DirKind == OpenACCDirectiveKind::Kernels) { 1062*0fca6ea1SDimitry Andric assert(SemaRef.ParentlessLoopConstructs.empty() && 1063*0fca6ea1SDimitry Andric "Didn't consume loop construct list?"); 1064*0fca6ea1SDimitry Andric SemaRef.ParentlessLoopConstructs.swap(ParentlessLoopConstructs); 1065*0fca6ea1SDimitry Andric } 1066*0fca6ea1SDimitry Andric } 1067*0fca6ea1SDimitry Andric 1068*0fca6ea1SDimitry Andric OpenACCClause * 1069*0fca6ea1SDimitry Andric SemaOpenACC::ActOnClause(ArrayRef<const OpenACCClause *> ExistingClauses, 1070*0fca6ea1SDimitry Andric OpenACCParsedClause &Clause) { 1071*0fca6ea1SDimitry Andric if (Clause.getClauseKind() == OpenACCClauseKind::Invalid) 1072*0fca6ea1SDimitry Andric return nullptr; 1073*0fca6ea1SDimitry Andric 1074*0fca6ea1SDimitry Andric // Diagnose that we don't support this clause on this directive. 1075*0fca6ea1SDimitry Andric if (!doesClauseApplyToDirective(Clause.getDirectiveKind(), 1076*0fca6ea1SDimitry Andric Clause.getClauseKind())) { 1077*0fca6ea1SDimitry Andric Diag(Clause.getBeginLoc(), diag::err_acc_clause_appertainment) 1078*0fca6ea1SDimitry Andric << Clause.getDirectiveKind() << Clause.getClauseKind(); 1079*0fca6ea1SDimitry Andric return nullptr; 1080*0fca6ea1SDimitry Andric } 1081*0fca6ea1SDimitry Andric 1082*0fca6ea1SDimitry Andric if (const auto *DevTypeClause = 1083*0fca6ea1SDimitry Andric llvm::find_if(ExistingClauses, 1084*0fca6ea1SDimitry Andric [&](const OpenACCClause *C) { 1085*0fca6ea1SDimitry Andric return isa<OpenACCDeviceTypeClause>(C); 1086*0fca6ea1SDimitry Andric }); 1087*0fca6ea1SDimitry Andric DevTypeClause != ExistingClauses.end()) { 1088*0fca6ea1SDimitry Andric if (checkValidAfterDeviceType( 1089*0fca6ea1SDimitry Andric *this, *cast<OpenACCDeviceTypeClause>(*DevTypeClause), Clause)) 1090*0fca6ea1SDimitry Andric return nullptr; 1091*0fca6ea1SDimitry Andric } 1092*0fca6ea1SDimitry Andric 1093*0fca6ea1SDimitry Andric SemaOpenACCClauseVisitor Visitor{*this, ExistingClauses}; 1094*0fca6ea1SDimitry Andric OpenACCClause *Result = Visitor.Visit(Clause); 1095*0fca6ea1SDimitry Andric assert((!Result || Result->getClauseKind() == Clause.getClauseKind()) && 1096*0fca6ea1SDimitry Andric "Created wrong clause?"); 1097*0fca6ea1SDimitry Andric 1098*0fca6ea1SDimitry Andric if (Visitor.diagNotImplemented()) 1099*0fca6ea1SDimitry Andric Diag(Clause.getBeginLoc(), diag::warn_acc_clause_unimplemented) 1100*0fca6ea1SDimitry Andric << Clause.getClauseKind(); 1101*0fca6ea1SDimitry Andric 1102*0fca6ea1SDimitry Andric return Result; 1103*0fca6ea1SDimitry Andric 1104*0fca6ea1SDimitry Andric // switch (Clause.getClauseKind()) { 1105*0fca6ea1SDimitry Andric // case OpenACCClauseKind::PresentOrCopy: 1106*0fca6ea1SDimitry Andric // case OpenACCClauseKind::PCopy: 1107*0fca6ea1SDimitry Andric // Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) 1108*0fca6ea1SDimitry Andric // << Clause.getClauseKind() << OpenACCClauseKind::Copy; 1109*0fca6ea1SDimitry Andric // LLVM_FALLTHROUGH; 1110*0fca6ea1SDimitry Andric // case OpenACCClauseKind::PresentOrCreate: 1111*0fca6ea1SDimitry Andric // case OpenACCClauseKind::PCreate: 1112*0fca6ea1SDimitry Andric // Diag(Clause.getBeginLoc(), diag::warn_acc_deprecated_alias_name) 1113*0fca6ea1SDimitry Andric // << Clause.getClauseKind() << OpenACCClauseKind::Create; 1114*0fca6ea1SDimitry Andric // LLVM_FALLTHROUGH; 1115*0fca6ea1SDimitry Andric // 1116*0fca6ea1SDimitry Andric // 1117*0fca6ea1SDimitry Andric // 1118*0fca6ea1SDimitry Andric // 1119*0fca6ea1SDimitry Andric // case OpenACCClauseKind::DType: 1120*0fca6ea1SDimitry Andric // 1121*0fca6ea1SDimitry Andric // 1122*0fca6ea1SDimitry Andric // 1123*0fca6ea1SDimitry Andric // 1124*0fca6ea1SDimitry Andric // 1125*0fca6ea1SDimitry Andric // 1126*0fca6ea1SDimitry Andric // 1127*0fca6ea1SDimitry Andric // 1128*0fca6ea1SDimitry Andric // case OpenACCClauseKind::Gang: 1129*0fca6ea1SDimitry Andric // case OpenACCClauseKind::Worker: 1130*0fca6ea1SDimitry Andric // case OpenACCClauseKind::Vector: { 1131*0fca6ea1SDimitry Andric // // OpenACC 3.3 2.9: 1132*0fca6ea1SDimitry Andric // // A 'gang', 'worker', or 'vector' clause may not appear if a 'seq' 1133*0fca6ea1SDimitry Andric // clause 1134*0fca6ea1SDimitry Andric // // appears. 1135*0fca6ea1SDimitry Andric // const auto *Itr = 1136*0fca6ea1SDimitry Andric // llvm::find_if(ExistingClauses, llvm::IsaPred<OpenACCSeqClause>); 1137*0fca6ea1SDimitry Andric // 1138*0fca6ea1SDimitry Andric // if (Itr != ExistingClauses.end()) { 1139*0fca6ea1SDimitry Andric // Diag(Clause.getBeginLoc(), diag::err_acc_clause_cannot_combine) 1140*0fca6ea1SDimitry Andric // << Clause.getClauseKind() << (*Itr)->getClauseKind(); 1141*0fca6ea1SDimitry Andric // Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); 1142*0fca6ea1SDimitry Andric // } 1143*0fca6ea1SDimitry Andric // // Not yet implemented, so immediately drop to the 'not yet implemented' 1144*0fca6ea1SDimitry Andric // // diagnostic. 1145*0fca6ea1SDimitry Andric // break; 1146*0fca6ea1SDimitry Andric // } 1147*0fca6ea1SDimitry Andric // */ 1148*0fca6ea1SDimitry Andric 1149*0fca6ea1SDimitry Andric } 1150*0fca6ea1SDimitry Andric 1151*0fca6ea1SDimitry Andric /// OpenACC 3.3 section 2.5.15: 1152*0fca6ea1SDimitry Andric /// At a mininmum, the supported data types include ... the numerical data types 1153*0fca6ea1SDimitry Andric /// in C, C++, and Fortran. 1154*0fca6ea1SDimitry Andric /// 1155*0fca6ea1SDimitry Andric /// If the reduction var is a composite variable, each 1156*0fca6ea1SDimitry Andric /// member of the composite variable must be a supported datatype for the 1157*0fca6ea1SDimitry Andric /// reduction operation. 1158*0fca6ea1SDimitry Andric ExprResult SemaOpenACC::CheckReductionVar(Expr *VarExpr) { 1159*0fca6ea1SDimitry Andric VarExpr = VarExpr->IgnoreParenCasts(); 1160*0fca6ea1SDimitry Andric 1161*0fca6ea1SDimitry Andric auto TypeIsValid = [](QualType Ty) { 1162*0fca6ea1SDimitry Andric return Ty->isDependentType() || Ty->isScalarType(); 1163*0fca6ea1SDimitry Andric }; 1164*0fca6ea1SDimitry Andric 1165*0fca6ea1SDimitry Andric if (isa<ArraySectionExpr>(VarExpr)) { 1166*0fca6ea1SDimitry Andric Expr *ASExpr = VarExpr; 1167*0fca6ea1SDimitry Andric QualType BaseTy = ArraySectionExpr::getBaseOriginalType(ASExpr); 1168*0fca6ea1SDimitry Andric QualType EltTy = getASTContext().getBaseElementType(BaseTy); 1169*0fca6ea1SDimitry Andric 1170*0fca6ea1SDimitry Andric if (!TypeIsValid(EltTy)) { 1171*0fca6ea1SDimitry Andric Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type) 1172*0fca6ea1SDimitry Andric << EltTy << /*Sub array base type*/ 1; 1173*0fca6ea1SDimitry Andric return ExprError(); 1174*0fca6ea1SDimitry Andric } 1175*0fca6ea1SDimitry Andric } else if (auto *RD = VarExpr->getType()->getAsRecordDecl()) { 1176*0fca6ea1SDimitry Andric if (!RD->isStruct() && !RD->isClass()) { 1177*0fca6ea1SDimitry Andric Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) 1178*0fca6ea1SDimitry Andric << /*not class or struct*/ 0 << VarExpr->getType(); 1179*0fca6ea1SDimitry Andric return ExprError(); 1180*0fca6ea1SDimitry Andric } 1181*0fca6ea1SDimitry Andric 1182*0fca6ea1SDimitry Andric if (!RD->isCompleteDefinition()) { 1183*0fca6ea1SDimitry Andric Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) 1184*0fca6ea1SDimitry Andric << /*incomplete*/ 1 << VarExpr->getType(); 1185*0fca6ea1SDimitry Andric return ExprError(); 1186*0fca6ea1SDimitry Andric } 1187*0fca6ea1SDimitry Andric if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD); 1188*0fca6ea1SDimitry Andric CXXRD && !CXXRD->isAggregate()) { 1189*0fca6ea1SDimitry Andric Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_composite_type) 1190*0fca6ea1SDimitry Andric << /*aggregate*/ 2 << VarExpr->getType(); 1191*0fca6ea1SDimitry Andric return ExprError(); 1192*0fca6ea1SDimitry Andric } 1193*0fca6ea1SDimitry Andric 1194*0fca6ea1SDimitry Andric for (FieldDecl *FD : RD->fields()) { 1195*0fca6ea1SDimitry Andric if (!TypeIsValid(FD->getType())) { 1196*0fca6ea1SDimitry Andric Diag(VarExpr->getExprLoc(), 1197*0fca6ea1SDimitry Andric diag::err_acc_reduction_composite_member_type); 1198*0fca6ea1SDimitry Andric Diag(FD->getLocation(), diag::note_acc_reduction_composite_member_loc); 1199*0fca6ea1SDimitry Andric return ExprError(); 1200*0fca6ea1SDimitry Andric } 1201*0fca6ea1SDimitry Andric } 1202*0fca6ea1SDimitry Andric } else if (!TypeIsValid(VarExpr->getType())) { 1203*0fca6ea1SDimitry Andric Diag(VarExpr->getExprLoc(), diag::err_acc_reduction_type) 1204*0fca6ea1SDimitry Andric << VarExpr->getType() << /*Sub array base type*/ 0; 1205*0fca6ea1SDimitry Andric return ExprError(); 1206*0fca6ea1SDimitry Andric } 1207*0fca6ea1SDimitry Andric 1208*0fca6ea1SDimitry Andric return VarExpr; 1209*0fca6ea1SDimitry Andric } 1210*0fca6ea1SDimitry Andric 1211*0fca6ea1SDimitry Andric void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K, 1212*0fca6ea1SDimitry Andric SourceLocation DirLoc) { 1213*0fca6ea1SDimitry Andric switch (K) { 1214*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Invalid: 1215*0fca6ea1SDimitry Andric // Nothing to do here, an invalid kind has nothing we can check here. We 1216*0fca6ea1SDimitry Andric // want to continue parsing clauses as far as we can, so we will just 1217*0fca6ea1SDimitry Andric // ensure that we can still work and don't check any construct-specific 1218*0fca6ea1SDimitry Andric // rules anywhere. 1219*0fca6ea1SDimitry Andric break; 1220*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 1221*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 1222*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 1223*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Loop: 1224*0fca6ea1SDimitry Andric // Nothing to do here, there is no real legalization that needs to happen 1225*0fca6ea1SDimitry Andric // here as these constructs do not take any arguments. 1226*0fca6ea1SDimitry Andric break; 1227*0fca6ea1SDimitry Andric default: 1228*0fca6ea1SDimitry Andric Diag(DirLoc, diag::warn_acc_construct_unimplemented) << K; 1229*0fca6ea1SDimitry Andric break; 1230*0fca6ea1SDimitry Andric } 1231*0fca6ea1SDimitry Andric } 1232*0fca6ea1SDimitry Andric 1233*0fca6ea1SDimitry Andric ExprResult SemaOpenACC::ActOnIntExpr(OpenACCDirectiveKind DK, 1234*0fca6ea1SDimitry Andric OpenACCClauseKind CK, SourceLocation Loc, 1235*0fca6ea1SDimitry Andric Expr *IntExpr) { 1236*0fca6ea1SDimitry Andric 1237*0fca6ea1SDimitry Andric assert(((DK != OpenACCDirectiveKind::Invalid && 1238*0fca6ea1SDimitry Andric CK == OpenACCClauseKind::Invalid) || 1239*0fca6ea1SDimitry Andric (DK == OpenACCDirectiveKind::Invalid && 1240*0fca6ea1SDimitry Andric CK != OpenACCClauseKind::Invalid) || 1241*0fca6ea1SDimitry Andric (DK == OpenACCDirectiveKind::Invalid && 1242*0fca6ea1SDimitry Andric CK == OpenACCClauseKind::Invalid)) && 1243*0fca6ea1SDimitry Andric "Only one of directive or clause kind should be provided"); 1244*0fca6ea1SDimitry Andric 1245*0fca6ea1SDimitry Andric class IntExprConverter : public Sema::ICEConvertDiagnoser { 1246*0fca6ea1SDimitry Andric OpenACCDirectiveKind DirectiveKind; 1247*0fca6ea1SDimitry Andric OpenACCClauseKind ClauseKind; 1248*0fca6ea1SDimitry Andric Expr *IntExpr; 1249*0fca6ea1SDimitry Andric 1250*0fca6ea1SDimitry Andric // gets the index into the diagnostics so we can use this for clauses, 1251*0fca6ea1SDimitry Andric // directives, and sub array.s 1252*0fca6ea1SDimitry Andric unsigned getDiagKind() const { 1253*0fca6ea1SDimitry Andric if (ClauseKind != OpenACCClauseKind::Invalid) 1254*0fca6ea1SDimitry Andric return 0; 1255*0fca6ea1SDimitry Andric if (DirectiveKind != OpenACCDirectiveKind::Invalid) 1256*0fca6ea1SDimitry Andric return 1; 1257*0fca6ea1SDimitry Andric return 2; 1258*0fca6ea1SDimitry Andric } 1259*0fca6ea1SDimitry Andric 1260*0fca6ea1SDimitry Andric public: 1261*0fca6ea1SDimitry Andric IntExprConverter(OpenACCDirectiveKind DK, OpenACCClauseKind CK, 1262*0fca6ea1SDimitry Andric Expr *IntExpr) 1263*0fca6ea1SDimitry Andric : ICEConvertDiagnoser(/*AllowScopedEnumerations=*/false, 1264*0fca6ea1SDimitry Andric /*Suppress=*/false, 1265*0fca6ea1SDimitry Andric /*SuppressConversion=*/true), 1266*0fca6ea1SDimitry Andric DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {} 1267*0fca6ea1SDimitry Andric 1268*0fca6ea1SDimitry Andric bool match(QualType T) override { 1269*0fca6ea1SDimitry Andric // OpenACC spec just calls this 'integer expression' as having an 1270*0fca6ea1SDimitry Andric // 'integer type', so fall back on C99's 'integer type'. 1271*0fca6ea1SDimitry Andric return T->isIntegerType(); 1272*0fca6ea1SDimitry Andric } 1273*0fca6ea1SDimitry Andric SemaBase::SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 1274*0fca6ea1SDimitry Andric QualType T) override { 1275*0fca6ea1SDimitry Andric return S.Diag(Loc, diag::err_acc_int_expr_requires_integer) 1276*0fca6ea1SDimitry Andric << getDiagKind() << ClauseKind << DirectiveKind << T; 1277*0fca6ea1SDimitry Andric } 1278*0fca6ea1SDimitry Andric 1279*0fca6ea1SDimitry Andric SemaBase::SemaDiagnosticBuilder 1280*0fca6ea1SDimitry Andric diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override { 1281*0fca6ea1SDimitry Andric return S.Diag(Loc, diag::err_acc_int_expr_incomplete_class_type) 1282*0fca6ea1SDimitry Andric << T << IntExpr->getSourceRange(); 1283*0fca6ea1SDimitry Andric } 1284*0fca6ea1SDimitry Andric 1285*0fca6ea1SDimitry Andric SemaBase::SemaDiagnosticBuilder 1286*0fca6ea1SDimitry Andric diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, 1287*0fca6ea1SDimitry Andric QualType ConvTy) override { 1288*0fca6ea1SDimitry Andric return S.Diag(Loc, diag::err_acc_int_expr_explicit_conversion) 1289*0fca6ea1SDimitry Andric << T << ConvTy; 1290*0fca6ea1SDimitry Andric } 1291*0fca6ea1SDimitry Andric 1292*0fca6ea1SDimitry Andric SemaBase::SemaDiagnosticBuilder noteExplicitConv(Sema &S, 1293*0fca6ea1SDimitry Andric CXXConversionDecl *Conv, 1294*0fca6ea1SDimitry Andric QualType ConvTy) override { 1295*0fca6ea1SDimitry Andric return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion) 1296*0fca6ea1SDimitry Andric << ConvTy->isEnumeralType() << ConvTy; 1297*0fca6ea1SDimitry Andric } 1298*0fca6ea1SDimitry Andric 1299*0fca6ea1SDimitry Andric SemaBase::SemaDiagnosticBuilder 1300*0fca6ea1SDimitry Andric diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override { 1301*0fca6ea1SDimitry Andric return S.Diag(Loc, diag::err_acc_int_expr_multiple_conversions) << T; 1302*0fca6ea1SDimitry Andric } 1303*0fca6ea1SDimitry Andric 1304*0fca6ea1SDimitry Andric SemaBase::SemaDiagnosticBuilder 1305*0fca6ea1SDimitry Andric noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { 1306*0fca6ea1SDimitry Andric return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion) 1307*0fca6ea1SDimitry Andric << ConvTy->isEnumeralType() << ConvTy; 1308*0fca6ea1SDimitry Andric } 1309*0fca6ea1SDimitry Andric 1310*0fca6ea1SDimitry Andric SemaBase::SemaDiagnosticBuilder 1311*0fca6ea1SDimitry Andric diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, 1312*0fca6ea1SDimitry Andric QualType ConvTy) override { 1313*0fca6ea1SDimitry Andric llvm_unreachable("conversion functions are permitted"); 1314*0fca6ea1SDimitry Andric } 1315*0fca6ea1SDimitry Andric } IntExprDiagnoser(DK, CK, IntExpr); 1316*0fca6ea1SDimitry Andric 1317*0fca6ea1SDimitry Andric ExprResult IntExprResult = SemaRef.PerformContextualImplicitConversion( 1318*0fca6ea1SDimitry Andric Loc, IntExpr, IntExprDiagnoser); 1319*0fca6ea1SDimitry Andric if (IntExprResult.isInvalid()) 1320*0fca6ea1SDimitry Andric return ExprError(); 1321*0fca6ea1SDimitry Andric 1322*0fca6ea1SDimitry Andric IntExpr = IntExprResult.get(); 1323*0fca6ea1SDimitry Andric if (!IntExpr->isTypeDependent() && !IntExpr->getType()->isIntegerType()) 1324*0fca6ea1SDimitry Andric return ExprError(); 1325*0fca6ea1SDimitry Andric 1326*0fca6ea1SDimitry Andric // TODO OpenACC: Do we want to perform usual unary conversions here? When 1327*0fca6ea1SDimitry Andric // doing codegen we might find that is necessary, but skip it for now. 1328*0fca6ea1SDimitry Andric return IntExpr; 1329*0fca6ea1SDimitry Andric } 1330*0fca6ea1SDimitry Andric 1331*0fca6ea1SDimitry Andric bool SemaOpenACC::CheckVarIsPointerType(OpenACCClauseKind ClauseKind, 1332*0fca6ea1SDimitry Andric Expr *VarExpr) { 1333*0fca6ea1SDimitry Andric // We already know that VarExpr is a proper reference to a variable, so we 1334*0fca6ea1SDimitry Andric // should be able to just take the type of the expression to get the type of 1335*0fca6ea1SDimitry Andric // the referenced variable. 1336*0fca6ea1SDimitry Andric 1337*0fca6ea1SDimitry Andric // We've already seen an error, don't diagnose anything else. 1338*0fca6ea1SDimitry Andric if (!VarExpr || VarExpr->containsErrors()) 1339*0fca6ea1SDimitry Andric return false; 1340*0fca6ea1SDimitry Andric 1341*0fca6ea1SDimitry Andric if (isa<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()) || 1342*0fca6ea1SDimitry Andric VarExpr->hasPlaceholderType(BuiltinType::ArraySection)) { 1343*0fca6ea1SDimitry Andric Diag(VarExpr->getExprLoc(), diag::err_array_section_use) << /*OpenACC=*/0; 1344*0fca6ea1SDimitry Andric Diag(VarExpr->getExprLoc(), diag::note_acc_expected_pointer_var); 1345*0fca6ea1SDimitry Andric return true; 1346*0fca6ea1SDimitry Andric } 1347*0fca6ea1SDimitry Andric 1348*0fca6ea1SDimitry Andric QualType Ty = VarExpr->getType(); 1349*0fca6ea1SDimitry Andric Ty = Ty.getNonReferenceType().getUnqualifiedType(); 1350*0fca6ea1SDimitry Andric 1351*0fca6ea1SDimitry Andric // Nothing we can do if this is a dependent type. 1352*0fca6ea1SDimitry Andric if (Ty->isDependentType()) 1353*0fca6ea1SDimitry Andric return false; 1354*0fca6ea1SDimitry Andric 1355*0fca6ea1SDimitry Andric if (!Ty->isPointerType()) 1356*0fca6ea1SDimitry Andric return Diag(VarExpr->getExprLoc(), diag::err_acc_var_not_pointer_type) 1357*0fca6ea1SDimitry Andric << ClauseKind << Ty; 1358*0fca6ea1SDimitry Andric return false; 1359*0fca6ea1SDimitry Andric } 1360*0fca6ea1SDimitry Andric 1361*0fca6ea1SDimitry Andric ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) { 1362*0fca6ea1SDimitry Andric Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts(); 1363*0fca6ea1SDimitry Andric 1364*0fca6ea1SDimitry Andric // Sub-arrays/subscript-exprs are fine as long as the base is a 1365*0fca6ea1SDimitry Andric // VarExpr/MemberExpr. So strip all of those off. 1366*0fca6ea1SDimitry Andric while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) { 1367*0fca6ea1SDimitry Andric if (auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr)) 1368*0fca6ea1SDimitry Andric CurVarExpr = SubScrpt->getBase()->IgnoreParenImpCasts(); 1369*0fca6ea1SDimitry Andric else 1370*0fca6ea1SDimitry Andric CurVarExpr = 1371*0fca6ea1SDimitry Andric cast<ArraySectionExpr>(CurVarExpr)->getBase()->IgnoreParenImpCasts(); 1372*0fca6ea1SDimitry Andric } 1373*0fca6ea1SDimitry Andric 1374*0fca6ea1SDimitry Andric // References to a VarDecl are fine. 1375*0fca6ea1SDimitry Andric if (const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) { 1376*0fca6ea1SDimitry Andric if (isa<VarDecl, NonTypeTemplateParmDecl>( 1377*0fca6ea1SDimitry Andric DRE->getFoundDecl()->getCanonicalDecl())) 1378*0fca6ea1SDimitry Andric return VarExpr; 1379*0fca6ea1SDimitry Andric } 1380*0fca6ea1SDimitry Andric 1381*0fca6ea1SDimitry Andric // If CK is a Reduction, this special cases for OpenACC3.3 2.5.15: "A var in a 1382*0fca6ea1SDimitry Andric // reduction clause must be a scalar variable name, an aggregate variable 1383*0fca6ea1SDimitry Andric // name, an array element, or a subarray. 1384*0fca6ea1SDimitry Andric // A MemberExpr that references a Field is valid. 1385*0fca6ea1SDimitry Andric if (CK != OpenACCClauseKind::Reduction) { 1386*0fca6ea1SDimitry Andric if (const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) { 1387*0fca6ea1SDimitry Andric if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl())) 1388*0fca6ea1SDimitry Andric return VarExpr; 1389*0fca6ea1SDimitry Andric } 1390*0fca6ea1SDimitry Andric } 1391*0fca6ea1SDimitry Andric 1392*0fca6ea1SDimitry Andric // Referring to 'this' is always OK. 1393*0fca6ea1SDimitry Andric if (isa<CXXThisExpr>(CurVarExpr)) 1394*0fca6ea1SDimitry Andric return VarExpr; 1395*0fca6ea1SDimitry Andric 1396*0fca6ea1SDimitry Andric // Nothing really we can do here, as these are dependent. So just return they 1397*0fca6ea1SDimitry Andric // are valid. 1398*0fca6ea1SDimitry Andric if (isa<DependentScopeDeclRefExpr>(CurVarExpr) || 1399*0fca6ea1SDimitry Andric (CK != OpenACCClauseKind::Reduction && 1400*0fca6ea1SDimitry Andric isa<CXXDependentScopeMemberExpr>(CurVarExpr))) 1401*0fca6ea1SDimitry Andric return VarExpr; 1402*0fca6ea1SDimitry Andric 1403*0fca6ea1SDimitry Andric // There isn't really anything we can do in the case of a recovery expr, so 1404*0fca6ea1SDimitry Andric // skip the diagnostic rather than produce a confusing diagnostic. 1405*0fca6ea1SDimitry Andric if (isa<RecoveryExpr>(CurVarExpr)) 1406*0fca6ea1SDimitry Andric return ExprError(); 1407*0fca6ea1SDimitry Andric 1408*0fca6ea1SDimitry Andric Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref) 1409*0fca6ea1SDimitry Andric << (CK != OpenACCClauseKind::Reduction); 1410*0fca6ea1SDimitry Andric return ExprError(); 1411*0fca6ea1SDimitry Andric } 1412*0fca6ea1SDimitry Andric 1413*0fca6ea1SDimitry Andric ExprResult SemaOpenACC::ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, 1414*0fca6ea1SDimitry Andric Expr *LowerBound, 1415*0fca6ea1SDimitry Andric SourceLocation ColonLoc, 1416*0fca6ea1SDimitry Andric Expr *Length, 1417*0fca6ea1SDimitry Andric SourceLocation RBLoc) { 1418*0fca6ea1SDimitry Andric ASTContext &Context = getASTContext(); 1419*0fca6ea1SDimitry Andric 1420*0fca6ea1SDimitry Andric // Handle placeholders. 1421*0fca6ea1SDimitry Andric if (Base->hasPlaceholderType() && 1422*0fca6ea1SDimitry Andric !Base->hasPlaceholderType(BuiltinType::ArraySection)) { 1423*0fca6ea1SDimitry Andric ExprResult Result = SemaRef.CheckPlaceholderExpr(Base); 1424*0fca6ea1SDimitry Andric if (Result.isInvalid()) 1425*0fca6ea1SDimitry Andric return ExprError(); 1426*0fca6ea1SDimitry Andric Base = Result.get(); 1427*0fca6ea1SDimitry Andric } 1428*0fca6ea1SDimitry Andric if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) { 1429*0fca6ea1SDimitry Andric ExprResult Result = SemaRef.CheckPlaceholderExpr(LowerBound); 1430*0fca6ea1SDimitry Andric if (Result.isInvalid()) 1431*0fca6ea1SDimitry Andric return ExprError(); 1432*0fca6ea1SDimitry Andric Result = SemaRef.DefaultLvalueConversion(Result.get()); 1433*0fca6ea1SDimitry Andric if (Result.isInvalid()) 1434*0fca6ea1SDimitry Andric return ExprError(); 1435*0fca6ea1SDimitry Andric LowerBound = Result.get(); 1436*0fca6ea1SDimitry Andric } 1437*0fca6ea1SDimitry Andric if (Length && Length->getType()->isNonOverloadPlaceholderType()) { 1438*0fca6ea1SDimitry Andric ExprResult Result = SemaRef.CheckPlaceholderExpr(Length); 1439*0fca6ea1SDimitry Andric if (Result.isInvalid()) 1440*0fca6ea1SDimitry Andric return ExprError(); 1441*0fca6ea1SDimitry Andric Result = SemaRef.DefaultLvalueConversion(Result.get()); 1442*0fca6ea1SDimitry Andric if (Result.isInvalid()) 1443*0fca6ea1SDimitry Andric return ExprError(); 1444*0fca6ea1SDimitry Andric Length = Result.get(); 1445*0fca6ea1SDimitry Andric } 1446*0fca6ea1SDimitry Andric 1447*0fca6ea1SDimitry Andric // Check the 'base' value, it must be an array or pointer type, and not to/of 1448*0fca6ea1SDimitry Andric // a function type. 1449*0fca6ea1SDimitry Andric QualType OriginalBaseTy = ArraySectionExpr::getBaseOriginalType(Base); 1450*0fca6ea1SDimitry Andric QualType ResultTy; 1451*0fca6ea1SDimitry Andric if (!Base->isTypeDependent()) { 1452*0fca6ea1SDimitry Andric if (OriginalBaseTy->isAnyPointerType()) { 1453*0fca6ea1SDimitry Andric ResultTy = OriginalBaseTy->getPointeeType(); 1454*0fca6ea1SDimitry Andric } else if (OriginalBaseTy->isArrayType()) { 1455*0fca6ea1SDimitry Andric ResultTy = OriginalBaseTy->getAsArrayTypeUnsafe()->getElementType(); 1456*0fca6ea1SDimitry Andric } else { 1457*0fca6ea1SDimitry Andric return ExprError( 1458*0fca6ea1SDimitry Andric Diag(Base->getExprLoc(), diag::err_acc_typecheck_subarray_value) 1459*0fca6ea1SDimitry Andric << Base->getSourceRange()); 1460*0fca6ea1SDimitry Andric } 1461*0fca6ea1SDimitry Andric 1462*0fca6ea1SDimitry Andric if (ResultTy->isFunctionType()) { 1463*0fca6ea1SDimitry Andric Diag(Base->getExprLoc(), diag::err_acc_subarray_function_type) 1464*0fca6ea1SDimitry Andric << ResultTy << Base->getSourceRange(); 1465*0fca6ea1SDimitry Andric return ExprError(); 1466*0fca6ea1SDimitry Andric } 1467*0fca6ea1SDimitry Andric 1468*0fca6ea1SDimitry Andric if (SemaRef.RequireCompleteType(Base->getExprLoc(), ResultTy, 1469*0fca6ea1SDimitry Andric diag::err_acc_subarray_incomplete_type, 1470*0fca6ea1SDimitry Andric Base)) 1471*0fca6ea1SDimitry Andric return ExprError(); 1472*0fca6ea1SDimitry Andric 1473*0fca6ea1SDimitry Andric if (!Base->hasPlaceholderType(BuiltinType::ArraySection)) { 1474*0fca6ea1SDimitry Andric ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Base); 1475*0fca6ea1SDimitry Andric if (Result.isInvalid()) 1476*0fca6ea1SDimitry Andric return ExprError(); 1477*0fca6ea1SDimitry Andric Base = Result.get(); 1478*0fca6ea1SDimitry Andric } 1479*0fca6ea1SDimitry Andric } 1480*0fca6ea1SDimitry Andric 1481*0fca6ea1SDimitry Andric auto GetRecovery = [&](Expr *E, QualType Ty) { 1482*0fca6ea1SDimitry Andric ExprResult Recovery = 1483*0fca6ea1SDimitry Andric SemaRef.CreateRecoveryExpr(E->getBeginLoc(), E->getEndLoc(), E, Ty); 1484*0fca6ea1SDimitry Andric return Recovery.isUsable() ? Recovery.get() : nullptr; 1485*0fca6ea1SDimitry Andric }; 1486*0fca6ea1SDimitry Andric 1487*0fca6ea1SDimitry Andric // Ensure both of the expressions are int-exprs. 1488*0fca6ea1SDimitry Andric if (LowerBound && !LowerBound->isTypeDependent()) { 1489*0fca6ea1SDimitry Andric ExprResult LBRes = 1490*0fca6ea1SDimitry Andric ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid, 1491*0fca6ea1SDimitry Andric LowerBound->getExprLoc(), LowerBound); 1492*0fca6ea1SDimitry Andric 1493*0fca6ea1SDimitry Andric if (LBRes.isUsable()) 1494*0fca6ea1SDimitry Andric LBRes = SemaRef.DefaultLvalueConversion(LBRes.get()); 1495*0fca6ea1SDimitry Andric LowerBound = 1496*0fca6ea1SDimitry Andric LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy); 1497*0fca6ea1SDimitry Andric } 1498*0fca6ea1SDimitry Andric 1499*0fca6ea1SDimitry Andric if (Length && !Length->isTypeDependent()) { 1500*0fca6ea1SDimitry Andric ExprResult LenRes = 1501*0fca6ea1SDimitry Andric ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid, 1502*0fca6ea1SDimitry Andric Length->getExprLoc(), Length); 1503*0fca6ea1SDimitry Andric 1504*0fca6ea1SDimitry Andric if (LenRes.isUsable()) 1505*0fca6ea1SDimitry Andric LenRes = SemaRef.DefaultLvalueConversion(LenRes.get()); 1506*0fca6ea1SDimitry Andric Length = 1507*0fca6ea1SDimitry Andric LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy); 1508*0fca6ea1SDimitry Andric } 1509*0fca6ea1SDimitry Andric 1510*0fca6ea1SDimitry Andric // Length is required if the base type is not an array of known bounds. 1511*0fca6ea1SDimitry Andric if (!Length && (OriginalBaseTy.isNull() || 1512*0fca6ea1SDimitry Andric (!OriginalBaseTy->isDependentType() && 1513*0fca6ea1SDimitry Andric !OriginalBaseTy->isConstantArrayType() && 1514*0fca6ea1SDimitry Andric !OriginalBaseTy->isDependentSizedArrayType()))) { 1515*0fca6ea1SDimitry Andric bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType(); 1516*0fca6ea1SDimitry Andric Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray; 1517*0fca6ea1SDimitry Andric // Fill in a dummy 'length' so that when we instantiate this we don't 1518*0fca6ea1SDimitry Andric // double-diagnose here. 1519*0fca6ea1SDimitry Andric ExprResult Recovery = SemaRef.CreateRecoveryExpr( 1520*0fca6ea1SDimitry Andric ColonLoc, SourceLocation(), ArrayRef<Expr *>{std::nullopt}, 1521*0fca6ea1SDimitry Andric Context.IntTy); 1522*0fca6ea1SDimitry Andric Length = Recovery.isUsable() ? Recovery.get() : nullptr; 1523*0fca6ea1SDimitry Andric } 1524*0fca6ea1SDimitry Andric 1525*0fca6ea1SDimitry Andric // Check the values of each of the arguments, they cannot be negative(we 1526*0fca6ea1SDimitry Andric // assume), and if the array bound is known, must be within range. As we do 1527*0fca6ea1SDimitry Andric // so, do our best to continue with evaluation, we can set the 1528*0fca6ea1SDimitry Andric // value/expression to nullptr/nullopt if they are invalid, and treat them as 1529*0fca6ea1SDimitry Andric // not present for the rest of evaluation. 1530*0fca6ea1SDimitry Andric 1531*0fca6ea1SDimitry Andric // We don't have to check for dependence, because the dependent size is 1532*0fca6ea1SDimitry Andric // represented as a different AST node. 1533*0fca6ea1SDimitry Andric std::optional<llvm::APSInt> BaseSize; 1534*0fca6ea1SDimitry Andric if (!OriginalBaseTy.isNull() && OriginalBaseTy->isConstantArrayType()) { 1535*0fca6ea1SDimitry Andric const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy); 1536*0fca6ea1SDimitry Andric BaseSize = ArrayTy->getSize(); 1537*0fca6ea1SDimitry Andric } 1538*0fca6ea1SDimitry Andric 1539*0fca6ea1SDimitry Andric auto GetBoundValue = [&](Expr *E) -> std::optional<llvm::APSInt> { 1540*0fca6ea1SDimitry Andric if (!E || E->isInstantiationDependent()) 1541*0fca6ea1SDimitry Andric return std::nullopt; 1542*0fca6ea1SDimitry Andric 1543*0fca6ea1SDimitry Andric Expr::EvalResult Res; 1544*0fca6ea1SDimitry Andric if (!E->EvaluateAsInt(Res, Context)) 1545*0fca6ea1SDimitry Andric return std::nullopt; 1546*0fca6ea1SDimitry Andric return Res.Val.getInt(); 1547*0fca6ea1SDimitry Andric }; 1548*0fca6ea1SDimitry Andric 1549*0fca6ea1SDimitry Andric std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound); 1550*0fca6ea1SDimitry Andric std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length); 1551*0fca6ea1SDimitry Andric 1552*0fca6ea1SDimitry Andric // Check lower bound for negative or out of range. 1553*0fca6ea1SDimitry Andric if (LowerBoundValue.has_value()) { 1554*0fca6ea1SDimitry Andric if (LowerBoundValue->isNegative()) { 1555*0fca6ea1SDimitry Andric Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_negative) 1556*0fca6ea1SDimitry Andric << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10); 1557*0fca6ea1SDimitry Andric LowerBoundValue.reset(); 1558*0fca6ea1SDimitry Andric LowerBound = GetRecovery(LowerBound, LowerBound->getType()); 1559*0fca6ea1SDimitry Andric } else if (BaseSize.has_value() && 1560*0fca6ea1SDimitry Andric llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) { 1561*0fca6ea1SDimitry Andric // Lower bound (start index) must be less than the size of the array. 1562*0fca6ea1SDimitry Andric Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_out_of_range) 1563*0fca6ea1SDimitry Andric << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10) 1564*0fca6ea1SDimitry Andric << toString(*BaseSize, /*Radix=*/10); 1565*0fca6ea1SDimitry Andric LowerBoundValue.reset(); 1566*0fca6ea1SDimitry Andric LowerBound = GetRecovery(LowerBound, LowerBound->getType()); 1567*0fca6ea1SDimitry Andric } 1568*0fca6ea1SDimitry Andric } 1569*0fca6ea1SDimitry Andric 1570*0fca6ea1SDimitry Andric // Check length for negative or out of range. 1571*0fca6ea1SDimitry Andric if (LengthValue.has_value()) { 1572*0fca6ea1SDimitry Andric if (LengthValue->isNegative()) { 1573*0fca6ea1SDimitry Andric Diag(Length->getExprLoc(), diag::err_acc_subarray_negative) 1574*0fca6ea1SDimitry Andric << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10); 1575*0fca6ea1SDimitry Andric LengthValue.reset(); 1576*0fca6ea1SDimitry Andric Length = GetRecovery(Length, Length->getType()); 1577*0fca6ea1SDimitry Andric } else if (BaseSize.has_value() && 1578*0fca6ea1SDimitry Andric llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) { 1579*0fca6ea1SDimitry Andric // Length must be lessthan or EQUAL to the size of the array. 1580*0fca6ea1SDimitry Andric Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range) 1581*0fca6ea1SDimitry Andric << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10) 1582*0fca6ea1SDimitry Andric << toString(*BaseSize, /*Radix=*/10); 1583*0fca6ea1SDimitry Andric LengthValue.reset(); 1584*0fca6ea1SDimitry Andric Length = GetRecovery(Length, Length->getType()); 1585*0fca6ea1SDimitry Andric } 1586*0fca6ea1SDimitry Andric } 1587*0fca6ea1SDimitry Andric 1588*0fca6ea1SDimitry Andric // Adding two APSInts requires matching sign, so extract that here. 1589*0fca6ea1SDimitry Andric auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt { 1590*0fca6ea1SDimitry Andric if (LHS.isSigned() == RHS.isSigned()) 1591*0fca6ea1SDimitry Andric return LHS + RHS; 1592*0fca6ea1SDimitry Andric 1593*0fca6ea1SDimitry Andric unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1; 1594*0fca6ea1SDimitry Andric return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width), /*Signed=*/true); 1595*0fca6ea1SDimitry Andric }; 1596*0fca6ea1SDimitry Andric 1597*0fca6ea1SDimitry Andric // If we know all 3 values, we can diagnose that the total value would be out 1598*0fca6ea1SDimitry Andric // of range. 1599*0fca6ea1SDimitry Andric if (BaseSize.has_value() && LowerBoundValue.has_value() && 1600*0fca6ea1SDimitry Andric LengthValue.has_value() && 1601*0fca6ea1SDimitry Andric llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue), 1602*0fca6ea1SDimitry Andric *BaseSize) > 0) { 1603*0fca6ea1SDimitry Andric Diag(Base->getExprLoc(), 1604*0fca6ea1SDimitry Andric diag::err_acc_subarray_base_plus_length_out_of_range) 1605*0fca6ea1SDimitry Andric << toString(*LowerBoundValue, /*Radix=*/10) 1606*0fca6ea1SDimitry Andric << toString(*LengthValue, /*Radix=*/10) 1607*0fca6ea1SDimitry Andric << toString(*BaseSize, /*Radix=*/10); 1608*0fca6ea1SDimitry Andric 1609*0fca6ea1SDimitry Andric LowerBoundValue.reset(); 1610*0fca6ea1SDimitry Andric LowerBound = GetRecovery(LowerBound, LowerBound->getType()); 1611*0fca6ea1SDimitry Andric LengthValue.reset(); 1612*0fca6ea1SDimitry Andric Length = GetRecovery(Length, Length->getType()); 1613*0fca6ea1SDimitry Andric } 1614*0fca6ea1SDimitry Andric 1615*0fca6ea1SDimitry Andric // If any part of the expression is dependent, return a dependent sub-array. 1616*0fca6ea1SDimitry Andric QualType ArrayExprTy = Context.ArraySectionTy; 1617*0fca6ea1SDimitry Andric if (Base->isTypeDependent() || 1618*0fca6ea1SDimitry Andric (LowerBound && LowerBound->isInstantiationDependent()) || 1619*0fca6ea1SDimitry Andric (Length && Length->isInstantiationDependent())) 1620*0fca6ea1SDimitry Andric ArrayExprTy = Context.DependentTy; 1621*0fca6ea1SDimitry Andric 1622*0fca6ea1SDimitry Andric return new (Context) 1623*0fca6ea1SDimitry Andric ArraySectionExpr(Base, LowerBound, Length, ArrayExprTy, VK_LValue, 1624*0fca6ea1SDimitry Andric OK_Ordinary, ColonLoc, RBLoc); 1625*0fca6ea1SDimitry Andric } 1626*0fca6ea1SDimitry Andric 1627*0fca6ea1SDimitry Andric bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K, 1628*0fca6ea1SDimitry Andric SourceLocation StartLoc) { 1629*0fca6ea1SDimitry Andric return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true); 1630*0fca6ea1SDimitry Andric } 1631*0fca6ea1SDimitry Andric 1632*0fca6ea1SDimitry Andric StmtResult SemaOpenACC::ActOnEndStmtDirective(OpenACCDirectiveKind K, 1633*0fca6ea1SDimitry Andric SourceLocation StartLoc, 1634*0fca6ea1SDimitry Andric SourceLocation DirLoc, 1635*0fca6ea1SDimitry Andric SourceLocation EndLoc, 1636*0fca6ea1SDimitry Andric ArrayRef<OpenACCClause *> Clauses, 1637*0fca6ea1SDimitry Andric StmtResult AssocStmt) { 1638*0fca6ea1SDimitry Andric switch (K) { 1639*0fca6ea1SDimitry Andric default: 1640*0fca6ea1SDimitry Andric return StmtEmpty(); 1641*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Invalid: 1642*0fca6ea1SDimitry Andric return StmtError(); 1643*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 1644*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 1645*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: { 1646*0fca6ea1SDimitry Andric auto *ComputeConstruct = OpenACCComputeConstruct::Create( 1647*0fca6ea1SDimitry Andric getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses, 1648*0fca6ea1SDimitry Andric AssocStmt.isUsable() ? AssocStmt.get() : nullptr, 1649*0fca6ea1SDimitry Andric ParentlessLoopConstructs); 1650*0fca6ea1SDimitry Andric 1651*0fca6ea1SDimitry Andric ParentlessLoopConstructs.clear(); 1652*0fca6ea1SDimitry Andric return ComputeConstruct; 1653*0fca6ea1SDimitry Andric } 1654*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Loop: { 1655*0fca6ea1SDimitry Andric auto *LoopConstruct = OpenACCLoopConstruct::Create( 1656*0fca6ea1SDimitry Andric getASTContext(), StartLoc, DirLoc, EndLoc, Clauses, 1657*0fca6ea1SDimitry Andric AssocStmt.isUsable() ? AssocStmt.get() : nullptr); 1658*0fca6ea1SDimitry Andric 1659*0fca6ea1SDimitry Andric // If we are in the scope of a compute construct, add this to the list of 1660*0fca6ea1SDimitry Andric // loop constructs that need assigning to the next closing compute 1661*0fca6ea1SDimitry Andric // construct. 1662*0fca6ea1SDimitry Andric if (InsideComputeConstruct) 1663*0fca6ea1SDimitry Andric ParentlessLoopConstructs.push_back(LoopConstruct); 1664*0fca6ea1SDimitry Andric 1665*0fca6ea1SDimitry Andric return LoopConstruct; 1666*0fca6ea1SDimitry Andric } 1667*0fca6ea1SDimitry Andric } 1668*0fca6ea1SDimitry Andric llvm_unreachable("Unhandled case in directive handling?"); 1669*0fca6ea1SDimitry Andric } 1670*0fca6ea1SDimitry Andric 1671*0fca6ea1SDimitry Andric StmtResult SemaOpenACC::ActOnAssociatedStmt(SourceLocation DirectiveLoc, 1672*0fca6ea1SDimitry Andric OpenACCDirectiveKind K, 1673*0fca6ea1SDimitry Andric StmtResult AssocStmt) { 1674*0fca6ea1SDimitry Andric switch (K) { 1675*0fca6ea1SDimitry Andric default: 1676*0fca6ea1SDimitry Andric llvm_unreachable("Unimplemented associated statement application"); 1677*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Parallel: 1678*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Serial: 1679*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Kernels: 1680*0fca6ea1SDimitry Andric // There really isn't any checking here that could happen. As long as we 1681*0fca6ea1SDimitry Andric // have a statement to associate, this should be fine. 1682*0fca6ea1SDimitry Andric // OpenACC 3.3 Section 6: 1683*0fca6ea1SDimitry Andric // Structured Block: in C or C++, an executable statement, possibly 1684*0fca6ea1SDimitry Andric // compound, with a single entry at the top and a single exit at the 1685*0fca6ea1SDimitry Andric // bottom. 1686*0fca6ea1SDimitry Andric // FIXME: Should we reject DeclStmt's here? The standard isn't clear, and 1687*0fca6ea1SDimitry Andric // an interpretation of it is to allow this and treat the initializer as 1688*0fca6ea1SDimitry Andric // the 'structured block'. 1689*0fca6ea1SDimitry Andric return AssocStmt; 1690*0fca6ea1SDimitry Andric case OpenACCDirectiveKind::Loop: 1691*0fca6ea1SDimitry Andric if (AssocStmt.isUsable() && 1692*0fca6ea1SDimitry Andric !isa<CXXForRangeStmt, ForStmt>(AssocStmt.get())) { 1693*0fca6ea1SDimitry Andric Diag(AssocStmt.get()->getBeginLoc(), diag::err_acc_loop_not_for_loop); 1694*0fca6ea1SDimitry Andric Diag(DirectiveLoc, diag::note_acc_construct_here) << K; 1695*0fca6ea1SDimitry Andric return StmtError(); 1696*0fca6ea1SDimitry Andric } 1697*0fca6ea1SDimitry Andric // TODO OpenACC: 2.9 ~ line 2010 specifies that the associated loop has some 1698*0fca6ea1SDimitry Andric // restrictions when there is a 'seq' clause in place. We probably need to 1699*0fca6ea1SDimitry Andric // implement that, including piping in the clauses here. 1700*0fca6ea1SDimitry Andric return AssocStmt; 1701*0fca6ea1SDimitry Andric } 1702*0fca6ea1SDimitry Andric llvm_unreachable("Invalid associated statement application"); 1703*0fca6ea1SDimitry Andric } 1704*0fca6ea1SDimitry Andric 1705*0fca6ea1SDimitry Andric bool SemaOpenACC::ActOnStartDeclDirective(OpenACCDirectiveKind K, 1706*0fca6ea1SDimitry Andric SourceLocation StartLoc) { 1707*0fca6ea1SDimitry Andric return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false); 1708*0fca6ea1SDimitry Andric } 1709*0fca6ea1SDimitry Andric 1710*0fca6ea1SDimitry Andric DeclGroupRef SemaOpenACC::ActOnEndDeclDirective() { return DeclGroupRef{}; } 1711