1 //===--- SemaOpenACC.cpp - Semantic Analysis for OpenACC constructs -------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenACC constructs, and things 10 /// that are not clause specific. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/StmtOpenACC.h" 15 #include "clang/Basic/DiagnosticSema.h" 16 #include "clang/Basic/OpenACCKinds.h" 17 #include "clang/Sema/Sema.h" 18 #include "clang/Sema/SemaOpenACC.h" 19 #include "llvm/ADT/StringExtras.h" 20 #include "llvm/Support/Casting.h" 21 22 using namespace clang; 23 24 namespace { 25 bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K, 26 SourceLocation StartLoc, bool IsStmt) { 27 switch (K) { 28 default: 29 case OpenACCDirectiveKind::Invalid: 30 // Nothing to do here, both invalid and unimplemented don't really need to 31 // do anything. 32 break; 33 case OpenACCDirectiveKind::ParallelLoop: 34 case OpenACCDirectiveKind::SerialLoop: 35 case OpenACCDirectiveKind::KernelsLoop: 36 case OpenACCDirectiveKind::Parallel: 37 case OpenACCDirectiveKind::Serial: 38 case OpenACCDirectiveKind::Kernels: 39 case OpenACCDirectiveKind::Loop: 40 case OpenACCDirectiveKind::Data: 41 case OpenACCDirectiveKind::EnterData: 42 case OpenACCDirectiveKind::ExitData: 43 case OpenACCDirectiveKind::HostData: 44 case OpenACCDirectiveKind::Wait: 45 if (!IsStmt) 46 return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K; 47 break; 48 } 49 return false; 50 } 51 52 void CollectActiveReductionClauses( 53 llvm::SmallVector<OpenACCReductionClause *> &ActiveClauses, 54 ArrayRef<OpenACCClause *> CurClauses) { 55 for (auto *CurClause : CurClauses) { 56 if (auto *RedClause = dyn_cast<OpenACCReductionClause>(CurClause); 57 RedClause && !RedClause->getVarList().empty()) 58 ActiveClauses.push_back(RedClause); 59 } 60 } 61 62 // Depth needs to be preserved for all associated statements that aren't 63 // supposed to modify the compute/combined/loop construct information. 64 bool PreserveLoopRAIIDepthInAssociatedStmtRAII(OpenACCDirectiveKind DK) { 65 switch (DK) { 66 case OpenACCDirectiveKind::Parallel: 67 case OpenACCDirectiveKind::ParallelLoop: 68 case OpenACCDirectiveKind::Serial: 69 case OpenACCDirectiveKind::SerialLoop: 70 case OpenACCDirectiveKind::Kernels: 71 case OpenACCDirectiveKind::KernelsLoop: 72 case OpenACCDirectiveKind::Loop: 73 return false; 74 case OpenACCDirectiveKind::Data: 75 case OpenACCDirectiveKind::HostData: 76 return true; 77 case OpenACCDirectiveKind::EnterData: 78 case OpenACCDirectiveKind::ExitData: 79 case OpenACCDirectiveKind::Wait: 80 case OpenACCDirectiveKind::Init: 81 case OpenACCDirectiveKind::Shutdown: 82 case OpenACCDirectiveKind::Set: 83 case OpenACCDirectiveKind::Update: 84 llvm_unreachable("Doesn't have an associated stmt"); 85 default: 86 case OpenACCDirectiveKind::Invalid: 87 llvm_unreachable("Unhandled directive kind?"); 88 } 89 llvm_unreachable("Unhandled directive kind?"); 90 } 91 92 } // namespace 93 94 SemaOpenACC::SemaOpenACC(Sema &S) : SemaBase(S) {} 95 96 SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII( 97 SemaOpenACC &S, OpenACCDirectiveKind DK, SourceLocation DirLoc, 98 ArrayRef<const OpenACCClause *> UnInstClauses, 99 ArrayRef<OpenACCClause *> Clauses) 100 : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo), 101 DirKind(DK), OldLoopGangClauseOnKernel(S.LoopGangClauseOnKernel), 102 OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc), 103 OldLoopVectorClauseLoc(S.LoopVectorClauseLoc), 104 OldLoopWithoutSeqInfo(S.LoopWithoutSeqInfo), 105 ActiveReductionClauses(S.ActiveReductionClauses), 106 LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) { 107 108 // Compute constructs end up taking their 'loop'. 109 if (DirKind == OpenACCDirectiveKind::Parallel || 110 DirKind == OpenACCDirectiveKind::Serial || 111 DirKind == OpenACCDirectiveKind::Kernels) { 112 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses); 113 SemaRef.ActiveComputeConstructInfo.Kind = DirKind; 114 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses; 115 116 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels 117 // construct, the gang clause behaves as follows. ... The region of a loop 118 // with a gang clause may not contain another loop with a gang clause unless 119 // within a nested compute region. 120 // 121 // Implement the 'unless within a nested compute region' part. 122 SemaRef.LoopGangClauseOnKernel = {}; 123 SemaRef.LoopWorkerClauseLoc = {}; 124 SemaRef.LoopVectorClauseLoc = {}; 125 SemaRef.LoopWithoutSeqInfo = {}; 126 } else if (DirKind == OpenACCDirectiveKind::ParallelLoop || 127 DirKind == OpenACCDirectiveKind::SerialLoop || 128 DirKind == OpenACCDirectiveKind::KernelsLoop) { 129 SemaRef.ActiveComputeConstructInfo.Kind = DirKind; 130 SemaRef.ActiveComputeConstructInfo.Clauses = Clauses; 131 132 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses); 133 SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses); 134 SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses); 135 136 SemaRef.LoopGangClauseOnKernel = {}; 137 SemaRef.LoopWorkerClauseLoc = {}; 138 SemaRef.LoopVectorClauseLoc = {}; 139 140 // Set the active 'loop' location if there isn't a 'seq' on it, so we can 141 // diagnose the for loops. 142 SemaRef.LoopWithoutSeqInfo = {}; 143 if (Clauses.end() == 144 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>)) 145 SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc}; 146 147 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels 148 // construct, the gang clause behaves as follows. ... The region of a loop 149 // with a gang clause may not contain another loop with a gang clause unless 150 // within a nested compute region. 151 // 152 // We don't bother doing this when this is a template instantiation, as 153 // there is no reason to do these checks: the existance of a 154 // gang/kernels/etc cannot be dependent. 155 if (DirKind == OpenACCDirectiveKind::KernelsLoop && UnInstClauses.empty()) { 156 // This handles the 'outer loop' part of this. 157 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>); 158 if (Itr != Clauses.end()) 159 SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(), DirKind}; 160 } 161 162 if (UnInstClauses.empty()) { 163 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>); 164 if (Itr != Clauses.end()) 165 SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc(); 166 167 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>); 168 if (Itr2 != Clauses.end()) 169 SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc(); 170 } 171 } else if (DirKind == OpenACCDirectiveKind::Loop) { 172 CollectActiveReductionClauses(S.ActiveReductionClauses, Clauses); 173 SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses); 174 SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses); 175 176 // Set the active 'loop' location if there isn't a 'seq' on it, so we can 177 // diagnose the for loops. 178 SemaRef.LoopWithoutSeqInfo = {}; 179 if (Clauses.end() == 180 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSeqClause>)) 181 SemaRef.LoopWithoutSeqInfo = {DirKind, DirLoc}; 182 183 // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels 184 // construct, the gang clause behaves as follows. ... The region of a loop 185 // with a gang clause may not contain another loop with a gang clause unless 186 // within a nested compute region. 187 // 188 // We don't bother doing this when this is a template instantiation, as 189 // there is no reason to do these checks: the existance of a 190 // gang/kernels/etc cannot be dependent. 191 if (SemaRef.getActiveComputeConstructInfo().Kind == 192 OpenACCDirectiveKind::Kernels && 193 UnInstClauses.empty()) { 194 // This handles the 'outer loop' part of this. 195 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCGangClause>); 196 if (Itr != Clauses.end()) 197 SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(), 198 OpenACCDirectiveKind::Kernels}; 199 } 200 201 if (UnInstClauses.empty()) { 202 auto *Itr = llvm::find_if(Clauses, llvm::IsaPred<OpenACCWorkerClause>); 203 if (Itr != Clauses.end()) 204 SemaRef.LoopWorkerClauseLoc = (*Itr)->getBeginLoc(); 205 206 auto *Itr2 = llvm::find_if(Clauses, llvm::IsaPred<OpenACCVectorClause>); 207 if (Itr2 != Clauses.end()) 208 SemaRef.LoopVectorClauseLoc = (*Itr2)->getBeginLoc(); 209 } 210 } 211 } 212 213 void SemaOpenACC::AssociatedStmtRAII::SetCollapseInfoBeforeAssociatedStmt( 214 ArrayRef<const OpenACCClause *> UnInstClauses, 215 ArrayRef<OpenACCClause *> Clauses) { 216 217 // Reset this checking for loops that aren't covered in a RAII object. 218 SemaRef.LoopInfo.CurLevelHasLoopAlready = false; 219 SemaRef.CollapseInfo.CollapseDepthSatisfied = true; 220 SemaRef.TileInfo.TileDepthSatisfied = true; 221 222 // We make sure to take an optional list of uninstantiated clauses, so that 223 // we can check to make sure we don't 'double diagnose' in the event that 224 // the value of 'N' was not dependent in a template. We also ensure during 225 // Sema that there is only 1 collapse on each construct, so we can count on 226 // the fact that if both find a 'collapse', that they are the same one. 227 auto *CollapseClauseItr = 228 llvm::find_if(Clauses, llvm::IsaPred<OpenACCCollapseClause>); 229 auto *UnInstCollapseClauseItr = 230 llvm::find_if(UnInstClauses, llvm::IsaPred<OpenACCCollapseClause>); 231 232 if (Clauses.end() == CollapseClauseItr) 233 return; 234 235 OpenACCCollapseClause *CollapseClause = 236 cast<OpenACCCollapseClause>(*CollapseClauseItr); 237 238 SemaRef.CollapseInfo.ActiveCollapse = CollapseClause; 239 Expr *LoopCount = CollapseClause->getLoopCount(); 240 241 // If the loop count is still instantiation dependent, setting the depth 242 // counter isn't necessary, so return here. 243 if (!LoopCount || LoopCount->isInstantiationDependent()) 244 return; 245 246 // Suppress diagnostics if we've done a 'transform' where the previous version 247 // wasn't dependent, meaning we already diagnosed it. 248 if (UnInstCollapseClauseItr != UnInstClauses.end() && 249 !cast<OpenACCCollapseClause>(*UnInstCollapseClauseItr) 250 ->getLoopCount() 251 ->isInstantiationDependent()) 252 return; 253 254 SemaRef.CollapseInfo.CollapseDepthSatisfied = false; 255 SemaRef.CollapseInfo.CurCollapseCount = 256 cast<ConstantExpr>(LoopCount)->getResultAsAPSInt(); 257 SemaRef.CollapseInfo.DirectiveKind = DirKind; 258 } 259 260 void SemaOpenACC::AssociatedStmtRAII::SetTileInfoBeforeAssociatedStmt( 261 ArrayRef<const OpenACCClause *> UnInstClauses, 262 ArrayRef<OpenACCClause *> Clauses) { 263 // We don't diagnose if this is during instantiation, since the only thing we 264 // care about is the number of arguments, which we can figure out without 265 // instantiation, so we don't want to double-diagnose. 266 if (UnInstClauses.size() > 0) 267 return; 268 auto *TileClauseItr = 269 llvm::find_if(Clauses, llvm::IsaPred<OpenACCTileClause>); 270 271 if (Clauses.end() == TileClauseItr) 272 return; 273 274 OpenACCTileClause *TileClause = cast<OpenACCTileClause>(*TileClauseItr); 275 SemaRef.TileInfo.ActiveTile = TileClause; 276 SemaRef.TileInfo.TileDepthSatisfied = false; 277 SemaRef.TileInfo.CurTileCount = TileClause->getSizeExprs().size(); 278 SemaRef.TileInfo.DirectiveKind = DirKind; 279 } 280 281 SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() { 282 if (DirKind == OpenACCDirectiveKind::Parallel || 283 DirKind == OpenACCDirectiveKind::Serial || 284 DirKind == OpenACCDirectiveKind::Kernels || 285 DirKind == OpenACCDirectiveKind::Loop || 286 DirKind == OpenACCDirectiveKind::ParallelLoop || 287 DirKind == OpenACCDirectiveKind::SerialLoop || 288 DirKind == OpenACCDirectiveKind::KernelsLoop) { 289 SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo; 290 SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel; 291 SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc; 292 SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc; 293 SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo; 294 SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses); 295 } else if (DirKind == OpenACCDirectiveKind::Data || 296 DirKind == OpenACCDirectiveKind::HostData) { 297 // Intentionally doesn't reset the Loop, Compute Construct, or reduction 298 // effects. 299 } 300 } 301 302 void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K, 303 SourceLocation DirLoc) { 304 // Start an evaluation context to parse the clause arguments on. 305 SemaRef.PushExpressionEvaluationContext( 306 Sema::ExpressionEvaluationContext::PotentiallyEvaluated); 307 308 switch (K) { 309 case OpenACCDirectiveKind::Invalid: 310 // Nothing to do here, an invalid kind has nothing we can check here. We 311 // want to continue parsing clauses as far as we can, so we will just 312 // ensure that we can still work and don't check any construct-specific 313 // rules anywhere. 314 break; 315 case OpenACCDirectiveKind::Parallel: 316 case OpenACCDirectiveKind::Serial: 317 case OpenACCDirectiveKind::Kernels: 318 case OpenACCDirectiveKind::ParallelLoop: 319 case OpenACCDirectiveKind::SerialLoop: 320 case OpenACCDirectiveKind::KernelsLoop: 321 case OpenACCDirectiveKind::Loop: 322 case OpenACCDirectiveKind::Data: 323 case OpenACCDirectiveKind::EnterData: 324 case OpenACCDirectiveKind::ExitData: 325 case OpenACCDirectiveKind::HostData: 326 case OpenACCDirectiveKind::Init: 327 case OpenACCDirectiveKind::Shutdown: 328 case OpenACCDirectiveKind::Set: 329 case OpenACCDirectiveKind::Update: 330 // Nothing to do here, there is no real legalization that needs to happen 331 // here as these constructs do not take any arguments. 332 break; 333 case OpenACCDirectiveKind::Wait: 334 // Nothing really to do here, the arguments to the 'wait' should have 335 // already been handled by the time we get here. 336 break; 337 default: 338 Diag(DirLoc, diag::warn_acc_construct_unimplemented) << K; 339 break; 340 } 341 } 342 343 ExprResult SemaOpenACC::ActOnIntExpr(OpenACCDirectiveKind DK, 344 OpenACCClauseKind CK, SourceLocation Loc, 345 Expr *IntExpr) { 346 347 assert(((DK != OpenACCDirectiveKind::Invalid && 348 CK == OpenACCClauseKind::Invalid) || 349 (DK == OpenACCDirectiveKind::Invalid && 350 CK != OpenACCClauseKind::Invalid) || 351 (DK == OpenACCDirectiveKind::Invalid && 352 CK == OpenACCClauseKind::Invalid)) && 353 "Only one of directive or clause kind should be provided"); 354 355 class IntExprConverter : public Sema::ICEConvertDiagnoser { 356 OpenACCDirectiveKind DirectiveKind; 357 OpenACCClauseKind ClauseKind; 358 Expr *IntExpr; 359 360 // gets the index into the diagnostics so we can use this for clauses, 361 // directives, and sub array.s 362 unsigned getDiagKind() const { 363 if (ClauseKind != OpenACCClauseKind::Invalid) 364 return 0; 365 if (DirectiveKind != OpenACCDirectiveKind::Invalid) 366 return 1; 367 return 2; 368 } 369 370 public: 371 IntExprConverter(OpenACCDirectiveKind DK, OpenACCClauseKind CK, 372 Expr *IntExpr) 373 : ICEConvertDiagnoser(/*AllowScopedEnumerations=*/false, 374 /*Suppress=*/false, 375 /*SuppressConversion=*/true), 376 DirectiveKind(DK), ClauseKind(CK), IntExpr(IntExpr) {} 377 378 bool match(QualType T) override { 379 // OpenACC spec just calls this 'integer expression' as having an 380 // 'integer type', so fall back on C99's 'integer type'. 381 return T->isIntegerType(); 382 } 383 SemaBase::SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 384 QualType T) override { 385 return S.Diag(Loc, diag::err_acc_int_expr_requires_integer) 386 << getDiagKind() << ClauseKind << DirectiveKind << T; 387 } 388 389 SemaBase::SemaDiagnosticBuilder 390 diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override { 391 return S.Diag(Loc, diag::err_acc_int_expr_incomplete_class_type) 392 << T << IntExpr->getSourceRange(); 393 } 394 395 SemaBase::SemaDiagnosticBuilder 396 diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, 397 QualType ConvTy) override { 398 return S.Diag(Loc, diag::err_acc_int_expr_explicit_conversion) 399 << T << ConvTy; 400 } 401 402 SemaBase::SemaDiagnosticBuilder noteExplicitConv(Sema &S, 403 CXXConversionDecl *Conv, 404 QualType ConvTy) override { 405 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion) 406 << ConvTy->isEnumeralType() << ConvTy; 407 } 408 409 SemaBase::SemaDiagnosticBuilder 410 diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override { 411 return S.Diag(Loc, diag::err_acc_int_expr_multiple_conversions) << T; 412 } 413 414 SemaBase::SemaDiagnosticBuilder 415 noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override { 416 return S.Diag(Conv->getLocation(), diag::note_acc_int_expr_conversion) 417 << ConvTy->isEnumeralType() << ConvTy; 418 } 419 420 SemaBase::SemaDiagnosticBuilder 421 diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, 422 QualType ConvTy) override { 423 llvm_unreachable("conversion functions are permitted"); 424 } 425 } IntExprDiagnoser(DK, CK, IntExpr); 426 427 if (!IntExpr) 428 return ExprError(); 429 430 ExprResult IntExprResult = SemaRef.PerformContextualImplicitConversion( 431 Loc, IntExpr, IntExprDiagnoser); 432 if (IntExprResult.isInvalid()) 433 return ExprError(); 434 435 IntExpr = IntExprResult.get(); 436 if (!IntExpr->isTypeDependent() && !IntExpr->getType()->isIntegerType()) 437 return ExprError(); 438 439 // TODO OpenACC: Do we want to perform usual unary conversions here? When 440 // doing codegen we might find that is necessary, but skip it for now. 441 return IntExpr; 442 } 443 444 bool SemaOpenACC::CheckVarIsPointerType(OpenACCClauseKind ClauseKind, 445 Expr *VarExpr) { 446 // We already know that VarExpr is a proper reference to a variable, so we 447 // should be able to just take the type of the expression to get the type of 448 // the referenced variable. 449 450 // We've already seen an error, don't diagnose anything else. 451 if (!VarExpr || VarExpr->containsErrors()) 452 return false; 453 454 if (isa<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts()) || 455 VarExpr->hasPlaceholderType(BuiltinType::ArraySection)) { 456 Diag(VarExpr->getExprLoc(), diag::err_array_section_use) << /*OpenACC=*/0; 457 Diag(VarExpr->getExprLoc(), diag::note_acc_expected_pointer_var); 458 return true; 459 } 460 461 QualType Ty = VarExpr->getType(); 462 Ty = Ty.getNonReferenceType().getUnqualifiedType(); 463 464 // Nothing we can do if this is a dependent type. 465 if (Ty->isDependentType()) 466 return false; 467 468 if (!Ty->isPointerType()) 469 return Diag(VarExpr->getExprLoc(), diag::err_acc_var_not_pointer_type) 470 << ClauseKind << Ty; 471 return false; 472 } 473 474 ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) { 475 Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts(); 476 477 // 'use_device' doesn't allow array subscript or array sections. 478 // OpenACC3.3 2.8: 479 // A 'var' in a 'use_device' clause must be the name of a variable or array. 480 if (CK == OpenACCClauseKind::UseDevice && 481 isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) { 482 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device); 483 return ExprError(); 484 } 485 486 // Sub-arrays/subscript-exprs are fine as long as the base is a 487 // VarExpr/MemberExpr. So strip all of those off. 488 while (isa<ArraySectionExpr, ArraySubscriptExpr>(CurVarExpr)) { 489 if (auto *SubScrpt = dyn_cast<ArraySubscriptExpr>(CurVarExpr)) 490 CurVarExpr = SubScrpt->getBase()->IgnoreParenImpCasts(); 491 else 492 CurVarExpr = 493 cast<ArraySectionExpr>(CurVarExpr)->getBase()->IgnoreParenImpCasts(); 494 } 495 496 // References to a VarDecl are fine. 497 if (const auto *DRE = dyn_cast<DeclRefExpr>(CurVarExpr)) { 498 if (isa<VarDecl, NonTypeTemplateParmDecl>( 499 DRE->getFoundDecl()->getCanonicalDecl())) 500 return VarExpr; 501 } 502 503 // If CK is a Reduction, this special cases for OpenACC3.3 2.5.15: "A var in a 504 // reduction clause must be a scalar variable name, an aggregate variable 505 // name, an array element, or a subarray. 506 // If CK is a 'use_device', this also isn't valid, as it isn' the name of a 507 // variable or array. 508 // A MemberExpr that references a Field is valid for other clauses. 509 if (CK != OpenACCClauseKind::Reduction && 510 CK != OpenACCClauseKind::UseDevice) { 511 if (const auto *ME = dyn_cast<MemberExpr>(CurVarExpr)) { 512 if (isa<FieldDecl>(ME->getMemberDecl()->getCanonicalDecl())) 513 return VarExpr; 514 } 515 } 516 517 // Referring to 'this' is ok for the most part, but for 'use_device' doesn't 518 // fall into 'variable or array name' 519 if (CK != OpenACCClauseKind::UseDevice && isa<CXXThisExpr>(CurVarExpr)) 520 return VarExpr; 521 522 // Nothing really we can do here, as these are dependent. So just return they 523 // are valid. 524 if (isa<DependentScopeDeclRefExpr>(CurVarExpr) || 525 (CK != OpenACCClauseKind::Reduction && 526 isa<CXXDependentScopeMemberExpr>(CurVarExpr))) 527 return VarExpr; 528 529 // There isn't really anything we can do in the case of a recovery expr, so 530 // skip the diagnostic rather than produce a confusing diagnostic. 531 if (isa<RecoveryExpr>(CurVarExpr)) 532 return ExprError(); 533 534 if (CK == OpenACCClauseKind::UseDevice) 535 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device); 536 else 537 Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref) 538 << (CK != OpenACCClauseKind::Reduction); 539 return ExprError(); 540 } 541 542 ExprResult SemaOpenACC::ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, 543 Expr *LowerBound, 544 SourceLocation ColonLoc, 545 Expr *Length, 546 SourceLocation RBLoc) { 547 ASTContext &Context = getASTContext(); 548 549 // Handle placeholders. 550 if (Base->hasPlaceholderType() && 551 !Base->hasPlaceholderType(BuiltinType::ArraySection)) { 552 ExprResult Result = SemaRef.CheckPlaceholderExpr(Base); 553 if (Result.isInvalid()) 554 return ExprError(); 555 Base = Result.get(); 556 } 557 if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) { 558 ExprResult Result = SemaRef.CheckPlaceholderExpr(LowerBound); 559 if (Result.isInvalid()) 560 return ExprError(); 561 Result = SemaRef.DefaultLvalueConversion(Result.get()); 562 if (Result.isInvalid()) 563 return ExprError(); 564 LowerBound = Result.get(); 565 } 566 if (Length && Length->getType()->isNonOverloadPlaceholderType()) { 567 ExprResult Result = SemaRef.CheckPlaceholderExpr(Length); 568 if (Result.isInvalid()) 569 return ExprError(); 570 Result = SemaRef.DefaultLvalueConversion(Result.get()); 571 if (Result.isInvalid()) 572 return ExprError(); 573 Length = Result.get(); 574 } 575 576 // Check the 'base' value, it must be an array or pointer type, and not to/of 577 // a function type. 578 QualType OriginalBaseTy = ArraySectionExpr::getBaseOriginalType(Base); 579 QualType ResultTy; 580 if (!Base->isTypeDependent()) { 581 if (OriginalBaseTy->isAnyPointerType()) { 582 ResultTy = OriginalBaseTy->getPointeeType(); 583 } else if (OriginalBaseTy->isArrayType()) { 584 ResultTy = OriginalBaseTy->getAsArrayTypeUnsafe()->getElementType(); 585 } else { 586 return ExprError( 587 Diag(Base->getExprLoc(), diag::err_acc_typecheck_subarray_value) 588 << Base->getSourceRange()); 589 } 590 591 if (ResultTy->isFunctionType()) { 592 Diag(Base->getExprLoc(), diag::err_acc_subarray_function_type) 593 << ResultTy << Base->getSourceRange(); 594 return ExprError(); 595 } 596 597 if (SemaRef.RequireCompleteType(Base->getExprLoc(), ResultTy, 598 diag::err_acc_subarray_incomplete_type, 599 Base)) 600 return ExprError(); 601 602 if (!Base->hasPlaceholderType(BuiltinType::ArraySection)) { 603 ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Base); 604 if (Result.isInvalid()) 605 return ExprError(); 606 Base = Result.get(); 607 } 608 } 609 610 auto GetRecovery = [&](Expr *E, QualType Ty) { 611 ExprResult Recovery = 612 SemaRef.CreateRecoveryExpr(E->getBeginLoc(), E->getEndLoc(), E, Ty); 613 return Recovery.isUsable() ? Recovery.get() : nullptr; 614 }; 615 616 // Ensure both of the expressions are int-exprs. 617 if (LowerBound && !LowerBound->isTypeDependent()) { 618 ExprResult LBRes = 619 ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid, 620 LowerBound->getExprLoc(), LowerBound); 621 622 if (LBRes.isUsable()) 623 LBRes = SemaRef.DefaultLvalueConversion(LBRes.get()); 624 LowerBound = 625 LBRes.isUsable() ? LBRes.get() : GetRecovery(LowerBound, Context.IntTy); 626 } 627 628 if (Length && !Length->isTypeDependent()) { 629 ExprResult LenRes = 630 ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Invalid, 631 Length->getExprLoc(), Length); 632 633 if (LenRes.isUsable()) 634 LenRes = SemaRef.DefaultLvalueConversion(LenRes.get()); 635 Length = 636 LenRes.isUsable() ? LenRes.get() : GetRecovery(Length, Context.IntTy); 637 } 638 639 // Length is required if the base type is not an array of known bounds. 640 if (!Length && (OriginalBaseTy.isNull() || 641 (!OriginalBaseTy->isDependentType() && 642 !OriginalBaseTy->isConstantArrayType() && 643 !OriginalBaseTy->isDependentSizedArrayType()))) { 644 bool IsArray = !OriginalBaseTy.isNull() && OriginalBaseTy->isArrayType(); 645 Diag(ColonLoc, diag::err_acc_subarray_no_length) << IsArray; 646 // Fill in a dummy 'length' so that when we instantiate this we don't 647 // double-diagnose here. 648 ExprResult Recovery = SemaRef.CreateRecoveryExpr( 649 ColonLoc, SourceLocation(), ArrayRef<Expr *>(), Context.IntTy); 650 Length = Recovery.isUsable() ? Recovery.get() : nullptr; 651 } 652 653 // Check the values of each of the arguments, they cannot be negative(we 654 // assume), and if the array bound is known, must be within range. As we do 655 // so, do our best to continue with evaluation, we can set the 656 // value/expression to nullptr/nullopt if they are invalid, and treat them as 657 // not present for the rest of evaluation. 658 659 // We don't have to check for dependence, because the dependent size is 660 // represented as a different AST node. 661 std::optional<llvm::APSInt> BaseSize; 662 if (!OriginalBaseTy.isNull() && OriginalBaseTy->isConstantArrayType()) { 663 const auto *ArrayTy = Context.getAsConstantArrayType(OriginalBaseTy); 664 BaseSize = ArrayTy->getSize(); 665 } 666 667 auto GetBoundValue = [&](Expr *E) -> std::optional<llvm::APSInt> { 668 if (!E || E->isInstantiationDependent()) 669 return std::nullopt; 670 671 Expr::EvalResult Res; 672 if (!E->EvaluateAsInt(Res, Context)) 673 return std::nullopt; 674 return Res.Val.getInt(); 675 }; 676 677 std::optional<llvm::APSInt> LowerBoundValue = GetBoundValue(LowerBound); 678 std::optional<llvm::APSInt> LengthValue = GetBoundValue(Length); 679 680 // Check lower bound for negative or out of range. 681 if (LowerBoundValue.has_value()) { 682 if (LowerBoundValue->isNegative()) { 683 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_negative) 684 << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10); 685 LowerBoundValue.reset(); 686 LowerBound = GetRecovery(LowerBound, LowerBound->getType()); 687 } else if (BaseSize.has_value() && 688 llvm::APSInt::compareValues(*LowerBoundValue, *BaseSize) >= 0) { 689 // Lower bound (start index) must be less than the size of the array. 690 Diag(LowerBound->getExprLoc(), diag::err_acc_subarray_out_of_range) 691 << /*LowerBound=*/0 << toString(*LowerBoundValue, /*Radix=*/10) 692 << toString(*BaseSize, /*Radix=*/10); 693 LowerBoundValue.reset(); 694 LowerBound = GetRecovery(LowerBound, LowerBound->getType()); 695 } 696 } 697 698 // Check length for negative or out of range. 699 if (LengthValue.has_value()) { 700 if (LengthValue->isNegative()) { 701 Diag(Length->getExprLoc(), diag::err_acc_subarray_negative) 702 << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10); 703 LengthValue.reset(); 704 Length = GetRecovery(Length, Length->getType()); 705 } else if (BaseSize.has_value() && 706 llvm::APSInt::compareValues(*LengthValue, *BaseSize) > 0) { 707 // Length must be lessthan or EQUAL to the size of the array. 708 Diag(Length->getExprLoc(), diag::err_acc_subarray_out_of_range) 709 << /*Length=*/1 << toString(*LengthValue, /*Radix=*/10) 710 << toString(*BaseSize, /*Radix=*/10); 711 LengthValue.reset(); 712 Length = GetRecovery(Length, Length->getType()); 713 } 714 } 715 716 // Adding two APSInts requires matching sign, so extract that here. 717 auto AddAPSInt = [](llvm::APSInt LHS, llvm::APSInt RHS) -> llvm::APSInt { 718 if (LHS.isSigned() == RHS.isSigned()) 719 return LHS + RHS; 720 721 unsigned Width = std::max(LHS.getBitWidth(), RHS.getBitWidth()) + 1; 722 return llvm::APSInt(LHS.sext(Width) + RHS.sext(Width), /*Signed=*/true); 723 }; 724 725 // If we know all 3 values, we can diagnose that the total value would be out 726 // of range. 727 if (BaseSize.has_value() && LowerBoundValue.has_value() && 728 LengthValue.has_value() && 729 llvm::APSInt::compareValues(AddAPSInt(*LowerBoundValue, *LengthValue), 730 *BaseSize) > 0) { 731 Diag(Base->getExprLoc(), 732 diag::err_acc_subarray_base_plus_length_out_of_range) 733 << toString(*LowerBoundValue, /*Radix=*/10) 734 << toString(*LengthValue, /*Radix=*/10) 735 << toString(*BaseSize, /*Radix=*/10); 736 737 LowerBoundValue.reset(); 738 LowerBound = GetRecovery(LowerBound, LowerBound->getType()); 739 LengthValue.reset(); 740 Length = GetRecovery(Length, Length->getType()); 741 } 742 743 // If any part of the expression is dependent, return a dependent sub-array. 744 QualType ArrayExprTy = Context.ArraySectionTy; 745 if (Base->isTypeDependent() || 746 (LowerBound && LowerBound->isInstantiationDependent()) || 747 (Length && Length->isInstantiationDependent())) 748 ArrayExprTy = Context.DependentTy; 749 750 return new (Context) 751 ArraySectionExpr(Base, LowerBound, Length, ArrayExprTy, VK_LValue, 752 OK_Ordinary, ColonLoc, RBLoc); 753 } 754 755 void SemaOpenACC::ActOnWhileStmt(SourceLocation WhileLoc) { 756 if (!getLangOpts().OpenACC) 757 return; 758 759 if (!LoopInfo.TopLevelLoopSeen) 760 return; 761 762 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) { 763 Diag(WhileLoc, diag::err_acc_invalid_in_loop) 764 << /*while loop*/ 1 << CollapseInfo.DirectiveKind 765 << OpenACCClauseKind::Collapse; 766 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?"); 767 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(), 768 diag::note_acc_active_clause_here) 769 << OpenACCClauseKind::Collapse; 770 771 // Remove the value so that we don't get cascading errors in the body. The 772 // caller RAII object will restore this. 773 CollapseInfo.CurCollapseCount = std::nullopt; 774 } 775 776 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) { 777 Diag(WhileLoc, diag::err_acc_invalid_in_loop) 778 << /*while loop*/ 1 << TileInfo.DirectiveKind 779 << OpenACCClauseKind::Tile; 780 assert(TileInfo.ActiveTile && "tile count without object?"); 781 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here) 782 << OpenACCClauseKind::Tile; 783 784 // Remove the value so that we don't get cascading errors in the body. The 785 // caller RAII object will restore this. 786 TileInfo.CurTileCount = std::nullopt; 787 } 788 } 789 790 void SemaOpenACC::ActOnDoStmt(SourceLocation DoLoc) { 791 if (!getLangOpts().OpenACC) 792 return; 793 794 if (!LoopInfo.TopLevelLoopSeen) 795 return; 796 797 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) { 798 Diag(DoLoc, diag::err_acc_invalid_in_loop) 799 << /*do loop*/ 2 << CollapseInfo.DirectiveKind 800 << OpenACCClauseKind::Collapse; 801 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?"); 802 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(), 803 diag::note_acc_active_clause_here) 804 << OpenACCClauseKind::Collapse; 805 806 // Remove the value so that we don't get cascading errors in the body. The 807 // caller RAII object will restore this. 808 CollapseInfo.CurCollapseCount = std::nullopt; 809 } 810 811 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) { 812 Diag(DoLoc, diag::err_acc_invalid_in_loop) 813 << /*do loop*/ 2 << TileInfo.DirectiveKind << OpenACCClauseKind::Tile; 814 assert(TileInfo.ActiveTile && "tile count without object?"); 815 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here) 816 << OpenACCClauseKind::Tile; 817 818 // Remove the value so that we don't get cascading errors in the body. The 819 // caller RAII object will restore this. 820 TileInfo.CurTileCount = std::nullopt; 821 } 822 } 823 824 void SemaOpenACC::ForStmtBeginHelper(SourceLocation ForLoc, 825 ForStmtBeginChecker &C) { 826 assert(getLangOpts().OpenACC && "Check enabled when not OpenACC?"); 827 828 // Enable the while/do-while checking. 829 LoopInfo.TopLevelLoopSeen = true; 830 831 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) { 832 C.check(); 833 834 // OpenACC 3.3 2.9.1: 835 // Each associated loop, except the innermost, must contain exactly one loop 836 // or loop nest. 837 // This checks for more than 1 loop at the current level, the 838 // 'depth'-satisifed checking manages the 'not zero' case. 839 if (LoopInfo.CurLevelHasLoopAlready) { 840 Diag(ForLoc, diag::err_acc_clause_multiple_loops) 841 << CollapseInfo.DirectiveKind << OpenACCClauseKind::Collapse; 842 assert(CollapseInfo.ActiveCollapse && "No collapse object?"); 843 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(), 844 diag::note_acc_active_clause_here) 845 << OpenACCClauseKind::Collapse; 846 } else { 847 --(*CollapseInfo.CurCollapseCount); 848 849 // Once we've hit zero here, we know we have deep enough 'for' loops to 850 // get to the bottom. 851 if (*CollapseInfo.CurCollapseCount == 0) 852 CollapseInfo.CollapseDepthSatisfied = true; 853 } 854 } 855 856 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) { 857 C.check(); 858 859 if (LoopInfo.CurLevelHasLoopAlready) { 860 Diag(ForLoc, diag::err_acc_clause_multiple_loops) 861 << TileInfo.DirectiveKind << OpenACCClauseKind::Tile; 862 assert(TileInfo.ActiveTile && "No tile object?"); 863 Diag(TileInfo.ActiveTile->getBeginLoc(), 864 diag::note_acc_active_clause_here) 865 << OpenACCClauseKind::Tile; 866 } else { 867 --(*TileInfo.CurTileCount); 868 // Once we've hit zero here, we know we have deep enough 'for' loops to 869 // get to the bottom. 870 if (*TileInfo.CurTileCount == 0) 871 TileInfo.TileDepthSatisfied = true; 872 } 873 } 874 875 // Set this to 'false' for the body of this loop, so that the next level 876 // checks independently. 877 LoopInfo.CurLevelHasLoopAlready = false; 878 } 879 880 namespace { 881 bool isValidLoopVariableType(QualType LoopVarTy) { 882 // Just skip if it is dependent, it could be any of the below. 883 if (LoopVarTy->isDependentType()) 884 return true; 885 886 // The loop variable must be of integer, 887 if (LoopVarTy->isIntegerType()) 888 return true; 889 890 // C/C++ pointer, 891 if (LoopVarTy->isPointerType()) 892 return true; 893 894 // or C++ random-access iterator type. 895 if (const auto *RD = LoopVarTy->getAsCXXRecordDecl()) { 896 // Note: Only do CXXRecordDecl because RecordDecl can't be a random access 897 // iterator type! 898 899 // We could either do a lot of work to see if this matches 900 // random-access-iterator, but it seems that just checking that the 901 // 'iterator_category' typedef is more than sufficient. If programmers are 902 // willing to lie about this, we can let them. 903 904 for (const auto *TD : 905 llvm::make_filter_range(RD->decls(), llvm::IsaPred<TypedefNameDecl>)) { 906 const auto *TDND = cast<TypedefNameDecl>(TD)->getCanonicalDecl(); 907 908 if (TDND->getName() != "iterator_category") 909 continue; 910 911 // If there is no type for this decl, return false. 912 if (TDND->getUnderlyingType().isNull()) 913 return false; 914 915 const CXXRecordDecl *ItrCategoryDecl = 916 TDND->getUnderlyingType()->getAsCXXRecordDecl(); 917 918 // If the category isn't a record decl, it isn't the tag type. 919 if (!ItrCategoryDecl) 920 return false; 921 922 auto IsRandomAccessIteratorTag = [](const CXXRecordDecl *RD) { 923 if (RD->getName() != "random_access_iterator_tag") 924 return false; 925 // Checks just for std::random_access_iterator_tag. 926 return RD->getEnclosingNamespaceContext()->isStdNamespace(); 927 }; 928 929 if (IsRandomAccessIteratorTag(ItrCategoryDecl)) 930 return true; 931 932 // We can also support types inherited from the 933 // random_access_iterator_tag. 934 for (CXXBaseSpecifier BS : ItrCategoryDecl->bases()) { 935 936 if (IsRandomAccessIteratorTag(BS.getType()->getAsCXXRecordDecl())) 937 return true; 938 } 939 940 return false; 941 } 942 } 943 944 return false; 945 } 946 947 } // namespace 948 949 void SemaOpenACC::ForStmtBeginChecker::check() { 950 if (SemaRef.LoopWithoutSeqInfo.Kind == OpenACCDirectiveKind::Invalid) 951 return; 952 953 if (AlreadyChecked) 954 return; 955 AlreadyChecked = true; 956 957 // OpenACC3.3 2.1: 958 // A loop associated with a loop construct that does not have a seq clause 959 // must be written to meet all the following conditions: 960 // - The loop variable must be of integer, C/C++ pointer, or C++ random-access 961 // iterator type. 962 // - The loop variable must monotonically increase or decrease in the 963 // direction of its termination condition. 964 // - The loop trip count must be computable in constant time when entering the 965 // loop construct. 966 // 967 // For a C++ range-based for loop, the loop variable 968 // identified by the above conditions is the internal iterator, such as a 969 // pointer, that the compiler generates to iterate the range. it is not the 970 // variable declared by the for loop. 971 972 if (IsRangeFor) { 973 // If the range-for is being instantiated and didn't change, don't 974 // re-diagnose. 975 if (!RangeFor.has_value()) 976 return; 977 // For a range-for, we can assume everything is 'corect' other than the type 978 // of the iterator, so check that. 979 const DeclStmt *RangeStmt = (*RangeFor)->getBeginStmt(); 980 981 // In some dependent contexts, the autogenerated range statement doesn't get 982 // included until instantiation, so skip for now. 983 if (!RangeStmt) 984 return; 985 986 const ValueDecl *InitVar = cast<ValueDecl>(RangeStmt->getSingleDecl()); 987 QualType VarType = InitVar->getType().getNonReferenceType(); 988 if (!isValidLoopVariableType(VarType)) { 989 SemaRef.Diag(InitVar->getBeginLoc(), diag::err_acc_loop_variable_type) 990 << SemaRef.LoopWithoutSeqInfo.Kind << VarType; 991 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, 992 diag::note_acc_construct_here) 993 << SemaRef.LoopWithoutSeqInfo.Kind; 994 } 995 return; 996 } 997 998 // Else we are in normal 'ForStmt', so we can diagnose everything. 999 // We only have to check cond/inc if they have changed, but 'init' needs to 1000 // just suppress its diagnostics if it hasn't changed. 1001 const ValueDecl *InitVar = checkInit(); 1002 if (Cond.has_value()) 1003 checkCond(); 1004 if (Inc.has_value()) 1005 checkInc(InitVar); 1006 } 1007 const ValueDecl *SemaOpenACC::ForStmtBeginChecker::checkInit() { 1008 if (!Init) { 1009 if (InitChanged) { 1010 SemaRef.Diag(ForLoc, diag::err_acc_loop_variable) 1011 << SemaRef.LoopWithoutSeqInfo.Kind; 1012 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, 1013 diag::note_acc_construct_here) 1014 << SemaRef.LoopWithoutSeqInfo.Kind; 1015 } 1016 return nullptr; 1017 } 1018 1019 auto DiagLoopVar = [&]() { 1020 if (InitChanged) { 1021 SemaRef.Diag(Init->getBeginLoc(), diag::err_acc_loop_variable) 1022 << SemaRef.LoopWithoutSeqInfo.Kind; 1023 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, 1024 diag::note_acc_construct_here) 1025 << SemaRef.LoopWithoutSeqInfo.Kind; 1026 } 1027 return nullptr; 1028 }; 1029 1030 if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(Init)) 1031 Init = ExprTemp->getSubExpr(); 1032 if (const auto *E = dyn_cast<Expr>(Init)) 1033 Init = E->IgnoreParenImpCasts(); 1034 1035 const ValueDecl *InitVar = nullptr; 1036 1037 if (const auto *BO = dyn_cast<BinaryOperator>(Init)) { 1038 // Allow assignment operator here. 1039 1040 if (!BO->isAssignmentOp()) 1041 return DiagLoopVar(); 1042 1043 const Expr *LHS = BO->getLHS()->IgnoreParenImpCasts(); 1044 1045 if (const auto *DRE = dyn_cast<DeclRefExpr>(LHS)) 1046 InitVar = DRE->getDecl(); 1047 } else if (const auto *DS = dyn_cast<DeclStmt>(Init)) { 1048 // Allow T t = <whatever> 1049 if (!DS->isSingleDecl()) 1050 return DiagLoopVar(); 1051 1052 InitVar = dyn_cast<ValueDecl>(DS->getSingleDecl()); 1053 1054 // Ensure we have an initializer, unless this is a record/dependent type. 1055 1056 if (InitVar) { 1057 if (!isa<VarDecl>(InitVar)) 1058 return DiagLoopVar(); 1059 1060 if (!InitVar->getType()->isRecordType() && 1061 !InitVar->getType()->isDependentType() && 1062 !cast<VarDecl>(InitVar)->hasInit()) 1063 return DiagLoopVar(); 1064 } 1065 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(Init)) { 1066 // Allow assignment operator call. 1067 if (CE->getOperator() != OO_Equal) 1068 return DiagLoopVar(); 1069 1070 const Expr *LHS = CE->getArg(0)->IgnoreParenImpCasts(); 1071 1072 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 1073 InitVar = DRE->getDecl(); 1074 } else if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 1075 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 1076 InitVar = ME->getMemberDecl(); 1077 } 1078 } 1079 1080 if (!InitVar) 1081 return DiagLoopVar(); 1082 1083 InitVar = cast<ValueDecl>(InitVar->getCanonicalDecl()); 1084 QualType VarType = InitVar->getType().getNonReferenceType(); 1085 1086 // Since we have one, all we need to do is ensure it is the right type. 1087 if (!isValidLoopVariableType(VarType)) { 1088 if (InitChanged) { 1089 SemaRef.Diag(InitVar->getBeginLoc(), diag::err_acc_loop_variable_type) 1090 << SemaRef.LoopWithoutSeqInfo.Kind << VarType; 1091 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, 1092 diag::note_acc_construct_here) 1093 << SemaRef.LoopWithoutSeqInfo.Kind; 1094 } 1095 return nullptr; 1096 } 1097 1098 return InitVar; 1099 } 1100 void SemaOpenACC::ForStmtBeginChecker::checkCond() { 1101 if (!*Cond) { 1102 SemaRef.Diag(ForLoc, diag::err_acc_loop_terminating_condition) 1103 << SemaRef.LoopWithoutSeqInfo.Kind; 1104 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here) 1105 << SemaRef.LoopWithoutSeqInfo.Kind; 1106 } 1107 // Nothing else to do here. we could probably do some additional work to look 1108 // into the termination condition, but that error-prone. For now, we don't 1109 // implement anything other than 'there is a termination condition', and if 1110 // codegen/MLIR comes up with some necessary restrictions, we can implement 1111 // them here. 1112 } 1113 1114 void SemaOpenACC::ForStmtBeginChecker::checkInc(const ValueDecl *Init) { 1115 1116 if (!*Inc) { 1117 SemaRef.Diag(ForLoc, diag::err_acc_loop_not_monotonic) 1118 << SemaRef.LoopWithoutSeqInfo.Kind; 1119 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here) 1120 << SemaRef.LoopWithoutSeqInfo.Kind; 1121 return; 1122 } 1123 auto DiagIncVar = [this] { 1124 SemaRef.Diag((*Inc)->getBeginLoc(), diag::err_acc_loop_not_monotonic) 1125 << SemaRef.LoopWithoutSeqInfo.Kind; 1126 SemaRef.Diag(SemaRef.LoopWithoutSeqInfo.Loc, diag::note_acc_construct_here) 1127 << SemaRef.LoopWithoutSeqInfo.Kind; 1128 return; 1129 }; 1130 1131 if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(*Inc)) 1132 Inc = ExprTemp->getSubExpr(); 1133 if (const auto *E = dyn_cast<Expr>(*Inc)) 1134 Inc = E->IgnoreParenImpCasts(); 1135 1136 auto getDeclFromExpr = [](const Expr *E) -> const ValueDecl * { 1137 E = E->IgnoreParenImpCasts(); 1138 if (const auto *FE = dyn_cast<FullExpr>(E)) 1139 E = FE->getSubExpr(); 1140 1141 E = E->IgnoreParenImpCasts(); 1142 1143 if (!E) 1144 return nullptr; 1145 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 1146 return dyn_cast<ValueDecl>(DRE->getDecl()); 1147 1148 if (const auto *ME = dyn_cast<MemberExpr>(E)) 1149 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 1150 return ME->getMemberDecl(); 1151 1152 return nullptr; 1153 }; 1154 1155 const ValueDecl *IncVar = nullptr; 1156 1157 // Here we enforce the monotonically increase/decrease: 1158 if (const auto *UO = dyn_cast<UnaryOperator>(*Inc)) { 1159 // Allow increment/decrement ops. 1160 if (!UO->isIncrementDecrementOp()) 1161 return DiagIncVar(); 1162 IncVar = getDeclFromExpr(UO->getSubExpr()); 1163 } else if (const auto *BO = dyn_cast<BinaryOperator>(*Inc)) { 1164 switch (BO->getOpcode()) { 1165 default: 1166 return DiagIncVar(); 1167 case BO_AddAssign: 1168 case BO_SubAssign: 1169 case BO_MulAssign: 1170 case BO_DivAssign: 1171 case BO_Assign: 1172 // += -= *= /= should all be fine here, this should be all of the 1173 // 'monotonical' compound-assign ops. 1174 // Assignment we just give up on, we could do better, and ensure that it 1175 // is a binary/operator expr doing more work, but that seems like a lot 1176 // of work for an error prone check. 1177 break; 1178 } 1179 IncVar = getDeclFromExpr(BO->getLHS()); 1180 } else if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(*Inc)) { 1181 switch (CE->getOperator()) { 1182 default: 1183 return DiagIncVar(); 1184 case OO_PlusPlus: 1185 case OO_MinusMinus: 1186 case OO_PlusEqual: 1187 case OO_MinusEqual: 1188 case OO_StarEqual: 1189 case OO_SlashEqual: 1190 case OO_Equal: 1191 // += -= *= /= should all be fine here, this should be all of the 1192 // 'monotonical' compound-assign ops. 1193 // Assignment we just give up on, we could do better, and ensure that it 1194 // is a binary/operator expr doing more work, but that seems like a lot 1195 // of work for an error prone check. 1196 break; 1197 } 1198 1199 IncVar = getDeclFromExpr(CE->getArg(0)); 1200 1201 } else if (const auto *ME = dyn_cast<CXXMemberCallExpr>(*Inc)) { 1202 IncVar = getDeclFromExpr(ME->getImplicitObjectArgument()); 1203 // We can't really do much for member expressions, other than hope they are 1204 // doing the right thing, so give up here. 1205 } 1206 1207 if (!IncVar) 1208 return DiagIncVar(); 1209 1210 // InitVar shouldn't be null unless there was an error, so don't diagnose if 1211 // that is the case. Else we should ensure that it refers to the loop 1212 // value. 1213 if (Init && IncVar->getCanonicalDecl() != Init->getCanonicalDecl()) 1214 return DiagIncVar(); 1215 1216 return; 1217 } 1218 1219 void SemaOpenACC::ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *OldFirst, 1220 const Stmt *First, const Stmt *OldSecond, 1221 const Stmt *Second, const Stmt *OldThird, 1222 const Stmt *Third) { 1223 if (!getLangOpts().OpenACC) 1224 return; 1225 1226 std::optional<const Stmt *> S; 1227 if (OldSecond == Second) 1228 S = std::nullopt; 1229 else 1230 S = Second; 1231 std::optional<const Stmt *> T; 1232 if (OldThird == Third) 1233 S = std::nullopt; 1234 else 1235 S = Third; 1236 1237 bool InitChanged = false; 1238 if (OldFirst != First) { 1239 InitChanged = true; 1240 1241 // VarDecls are always rebuild because they are dependent, so we can do a 1242 // little work to suppress some of the double checking based on whether the 1243 // type is instantiation dependent. 1244 QualType OldVDTy; 1245 QualType NewVDTy; 1246 if (const auto *DS = dyn_cast<DeclStmt>(OldFirst)) 1247 if (const VarDecl *VD = dyn_cast_if_present<VarDecl>( 1248 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr)) 1249 OldVDTy = VD->getType(); 1250 if (const auto *DS = dyn_cast<DeclStmt>(First)) 1251 if (const VarDecl *VD = dyn_cast_if_present<VarDecl>( 1252 DS->isSingleDecl() ? DS->getSingleDecl() : nullptr)) 1253 NewVDTy = VD->getType(); 1254 1255 if (!OldVDTy.isNull() && !NewVDTy.isNull()) 1256 InitChanged = OldVDTy->isInstantiationDependentType() != 1257 NewVDTy->isInstantiationDependentType(); 1258 } 1259 1260 ForStmtBeginChecker FSBC{*this, ForLoc, First, InitChanged, S, T}; 1261 if (!LoopInfo.TopLevelLoopSeen) { 1262 FSBC.check(); 1263 } 1264 1265 ForStmtBeginHelper(ForLoc, FSBC); 1266 } 1267 1268 void SemaOpenACC::ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, 1269 const Stmt *Second, const Stmt *Third) { 1270 if (!getLangOpts().OpenACC) 1271 return; 1272 1273 ForStmtBeginChecker FSBC{*this, ForLoc, First, /*InitChanged=*/true, 1274 Second, Third}; 1275 if (!LoopInfo.TopLevelLoopSeen) { 1276 FSBC.check(); 1277 } 1278 1279 ForStmtBeginHelper(ForLoc, FSBC); 1280 } 1281 1282 void SemaOpenACC::ActOnRangeForStmtBegin(SourceLocation ForLoc, 1283 const Stmt *OldRangeFor, 1284 const Stmt *RangeFor) { 1285 if (!getLangOpts().OpenACC) 1286 return; 1287 1288 std::optional<const CXXForRangeStmt *> RF; 1289 1290 if (OldRangeFor == RangeFor) 1291 RF = std::nullopt; 1292 else 1293 RF = cast<CXXForRangeStmt>(RangeFor); 1294 1295 ForStmtBeginChecker FSBC{*this, ForLoc, RF}; 1296 if (!LoopInfo.TopLevelLoopSeen) { 1297 FSBC.check(); 1298 } 1299 ForStmtBeginHelper(ForLoc, FSBC); 1300 } 1301 1302 void SemaOpenACC::ActOnRangeForStmtBegin(SourceLocation ForLoc, 1303 const Stmt *RangeFor) { 1304 if (!getLangOpts().OpenACC) 1305 return; 1306 1307 ForStmtBeginChecker FSBC{*this, ForLoc, cast<CXXForRangeStmt>(RangeFor)}; 1308 if (!LoopInfo.TopLevelLoopSeen) { 1309 FSBC.check(); 1310 } 1311 ForStmtBeginHelper(ForLoc, FSBC); 1312 } 1313 1314 namespace { 1315 SourceLocation FindInterveningCodeInLoop(const Stmt *CurStmt) { 1316 // We should diagnose on anything except `CompoundStmt`, `NullStmt`, 1317 // `ForStmt`, `CXXForRangeStmt`, since those are legal, and `WhileStmt` and 1318 // `DoStmt`, as those are caught as a violation elsewhere. 1319 // For `CompoundStmt` we need to search inside of it. 1320 if (!CurStmt || 1321 isa<ForStmt, NullStmt, ForStmt, CXXForRangeStmt, WhileStmt, DoStmt>( 1322 CurStmt)) 1323 return SourceLocation{}; 1324 1325 // Any other construct is an error anyway, so it has already been diagnosed. 1326 if (isa<OpenACCConstructStmt>(CurStmt)) 1327 return SourceLocation{}; 1328 1329 // Search inside the compound statement, this allows for arbitrary nesting 1330 // of compound statements, as long as there isn't any code inside. 1331 if (const auto *CS = dyn_cast<CompoundStmt>(CurStmt)) { 1332 for (const auto *ChildStmt : CS->children()) { 1333 SourceLocation ChildStmtLoc = FindInterveningCodeInLoop(ChildStmt); 1334 if (ChildStmtLoc.isValid()) 1335 return ChildStmtLoc; 1336 } 1337 // Empty/not invalid compound statements are legal. 1338 return SourceLocation{}; 1339 } 1340 return CurStmt->getBeginLoc(); 1341 } 1342 } // namespace 1343 1344 void SemaOpenACC::ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body) { 1345 if (!getLangOpts().OpenACC) 1346 return; 1347 1348 // Set this to 'true' so if we find another one at this level we can diagnose. 1349 LoopInfo.CurLevelHasLoopAlready = true; 1350 1351 if (!Body.isUsable()) 1352 return; 1353 1354 bool IsActiveCollapse = CollapseInfo.CurCollapseCount && 1355 *CollapseInfo.CurCollapseCount > 0 && 1356 !CollapseInfo.ActiveCollapse->hasForce(); 1357 bool IsActiveTile = TileInfo.CurTileCount && *TileInfo.CurTileCount > 0; 1358 1359 if (IsActiveCollapse || IsActiveTile) { 1360 SourceLocation OtherStmtLoc = FindInterveningCodeInLoop(Body.get()); 1361 1362 if (OtherStmtLoc.isValid() && IsActiveCollapse) { 1363 Diag(OtherStmtLoc, diag::err_acc_intervening_code) 1364 << OpenACCClauseKind::Collapse << CollapseInfo.DirectiveKind; 1365 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(), 1366 diag::note_acc_active_clause_here) 1367 << OpenACCClauseKind::Collapse; 1368 } 1369 1370 if (OtherStmtLoc.isValid() && IsActiveTile) { 1371 Diag(OtherStmtLoc, diag::err_acc_intervening_code) 1372 << OpenACCClauseKind::Tile << TileInfo.DirectiveKind; 1373 Diag(TileInfo.ActiveTile->getBeginLoc(), 1374 diag::note_acc_active_clause_here) 1375 << OpenACCClauseKind::Tile; 1376 } 1377 } 1378 } 1379 1380 namespace { 1381 // Get a list of clause Kinds for diagnosing a list, joined by a commas and an 1382 // 'or'. 1383 std::string GetListOfClauses(llvm::ArrayRef<OpenACCClauseKind> Clauses) { 1384 assert(!Clauses.empty() && "empty clause list not supported"); 1385 1386 std::string Output; 1387 llvm::raw_string_ostream OS{Output}; 1388 1389 if (Clauses.size() == 1) { 1390 OS << '\'' << Clauses[0] << '\''; 1391 return Output; 1392 } 1393 1394 llvm::ArrayRef<OpenACCClauseKind> AllButLast{Clauses.begin(), 1395 Clauses.end() - 1}; 1396 1397 llvm::interleave( 1398 AllButLast, [&](OpenACCClauseKind K) { OS << '\'' << K << '\''; }, 1399 [&] { OS << ", "; }); 1400 1401 OS << " or \'" << Clauses.back() << '\''; 1402 return Output; 1403 } 1404 } // namespace 1405 1406 bool SemaOpenACC::ActOnStartStmtDirective( 1407 OpenACCDirectiveKind K, SourceLocation StartLoc, 1408 ArrayRef<const OpenACCClause *> Clauses) { 1409 SemaRef.DiscardCleanupsInEvaluationContext(); 1410 SemaRef.PopExpressionEvaluationContext(); 1411 1412 // OpenACC 3.3 2.9.1: 1413 // Intervening code must not contain other OpenACC directives or calls to API 1414 // routines. 1415 // 1416 // ALL constructs are ill-formed if there is an active 'collapse' 1417 if (CollapseInfo.CurCollapseCount && *CollapseInfo.CurCollapseCount > 0) { 1418 Diag(StartLoc, diag::err_acc_invalid_in_loop) 1419 << /*OpenACC Construct*/ 0 << CollapseInfo.DirectiveKind 1420 << OpenACCClauseKind::Collapse << K; 1421 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?"); 1422 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(), 1423 diag::note_acc_active_clause_here) 1424 << OpenACCClauseKind::Collapse; 1425 } 1426 if (TileInfo.CurTileCount && *TileInfo.CurTileCount > 0) { 1427 Diag(StartLoc, diag::err_acc_invalid_in_loop) 1428 << /*OpenACC Construct*/ 0 << TileInfo.DirectiveKind 1429 << OpenACCClauseKind::Tile << K; 1430 assert(TileInfo.ActiveTile && "Tile count without object?"); 1431 Diag(TileInfo.ActiveTile->getBeginLoc(), diag::note_acc_active_clause_here) 1432 << OpenACCClauseKind::Tile; 1433 } 1434 1435 // OpenACC3.3 2.6.5: At least one copy, copyin, copyout, create, no_create, 1436 // present, deviceptr, attach, or default clause must appear on a 'data' 1437 // construct. 1438 if (K == OpenACCDirectiveKind::Data && 1439 llvm::find_if(Clauses, 1440 llvm::IsaPred<OpenACCCopyClause, OpenACCCopyInClause, 1441 OpenACCCopyOutClause, OpenACCCreateClause, 1442 OpenACCNoCreateClause, OpenACCPresentClause, 1443 OpenACCDevicePtrClause, OpenACCAttachClause, 1444 OpenACCDefaultClause>) == Clauses.end()) 1445 return Diag(StartLoc, diag::err_acc_construct_one_clause_of) 1446 << K 1447 << GetListOfClauses( 1448 {OpenACCClauseKind::Copy, OpenACCClauseKind::CopyIn, 1449 OpenACCClauseKind::CopyOut, OpenACCClauseKind::Create, 1450 OpenACCClauseKind::NoCreate, OpenACCClauseKind::Present, 1451 OpenACCClauseKind::DevicePtr, OpenACCClauseKind::Attach, 1452 OpenACCClauseKind::Default}); 1453 1454 // OpenACC3.3 2.6.6: At least one copyin, create, or attach clause must appear 1455 // on an enter data directive. 1456 if (K == OpenACCDirectiveKind::EnterData && 1457 llvm::find_if(Clauses, 1458 llvm::IsaPred<OpenACCCopyInClause, OpenACCCreateClause, 1459 OpenACCAttachClause>) == Clauses.end()) 1460 return Diag(StartLoc, diag::err_acc_construct_one_clause_of) 1461 << K 1462 << GetListOfClauses({ 1463 OpenACCClauseKind::CopyIn, 1464 OpenACCClauseKind::Create, 1465 OpenACCClauseKind::Attach, 1466 }); 1467 // OpenACC3.3 2.6.6: At least one copyout, delete, or detach clause must 1468 // appear on an exit data directive. 1469 if (K == OpenACCDirectiveKind::ExitData && 1470 llvm::find_if(Clauses, 1471 llvm::IsaPred<OpenACCCopyOutClause, OpenACCDeleteClause, 1472 OpenACCDetachClause>) == Clauses.end()) 1473 return Diag(StartLoc, diag::err_acc_construct_one_clause_of) 1474 << K 1475 << GetListOfClauses({ 1476 OpenACCClauseKind::CopyOut, 1477 OpenACCClauseKind::Delete, 1478 OpenACCClauseKind::Detach, 1479 }); 1480 1481 // OpenACC3.3 2.8: At least 'one use_device' clause must appear. 1482 if (K == OpenACCDirectiveKind::HostData && 1483 llvm::find_if(Clauses, llvm::IsaPred<OpenACCUseDeviceClause>) == 1484 Clauses.end()) 1485 return Diag(StartLoc, diag::err_acc_construct_one_clause_of) 1486 << K << GetListOfClauses({OpenACCClauseKind::UseDevice}); 1487 1488 // OpenACC3.3 2.14.3: At least one default_async, device_num, or device_type 1489 // clause must appear. 1490 if (K == OpenACCDirectiveKind::Set && 1491 llvm::find_if( 1492 Clauses, 1493 llvm::IsaPred<OpenACCDefaultAsyncClause, OpenACCDeviceNumClause, 1494 OpenACCDeviceTypeClause, OpenACCIfClause>) == 1495 Clauses.end()) 1496 return Diag(StartLoc, diag::err_acc_construct_one_clause_of) 1497 << K 1498 << GetListOfClauses({OpenACCClauseKind::DefaultAsync, 1499 OpenACCClauseKind::DeviceNum, 1500 OpenACCClauseKind::DeviceType, 1501 OpenACCClauseKind::If}); 1502 1503 // OpenACC3.3 2.14.4: At least one self, host, or device clause must appear on 1504 // an update directive. 1505 if (K == OpenACCDirectiveKind::Update && 1506 llvm::find_if(Clauses, llvm::IsaPred<OpenACCSelfClause, OpenACCHostClause, 1507 OpenACCDeviceClause>) == 1508 Clauses.end()) 1509 return Diag(StartLoc, diag::err_acc_construct_one_clause_of) 1510 << K 1511 << GetListOfClauses({OpenACCClauseKind::Self, 1512 OpenACCClauseKind::Host, 1513 OpenACCClauseKind::Device}); 1514 1515 return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true); 1516 } 1517 1518 StmtResult SemaOpenACC::ActOnEndStmtDirective( 1519 OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, 1520 SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef<Expr *> Exprs, 1521 SourceLocation RParenLoc, SourceLocation EndLoc, 1522 ArrayRef<OpenACCClause *> Clauses, StmtResult AssocStmt) { 1523 switch (K) { 1524 default: 1525 return StmtEmpty(); 1526 case OpenACCDirectiveKind::Invalid: 1527 return StmtError(); 1528 case OpenACCDirectiveKind::Parallel: 1529 case OpenACCDirectiveKind::Serial: 1530 case OpenACCDirectiveKind::Kernels: { 1531 return OpenACCComputeConstruct::Create( 1532 getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses, 1533 AssocStmt.isUsable() ? AssocStmt.get() : nullptr); 1534 } 1535 case OpenACCDirectiveKind::ParallelLoop: 1536 case OpenACCDirectiveKind::SerialLoop: 1537 case OpenACCDirectiveKind::KernelsLoop: { 1538 return OpenACCCombinedConstruct::Create( 1539 getASTContext(), K, StartLoc, DirLoc, EndLoc, Clauses, 1540 AssocStmt.isUsable() ? AssocStmt.get() : nullptr); 1541 } 1542 case OpenACCDirectiveKind::Loop: { 1543 return OpenACCLoopConstruct::Create( 1544 getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc, 1545 EndLoc, Clauses, AssocStmt.isUsable() ? AssocStmt.get() : nullptr); 1546 } 1547 case OpenACCDirectiveKind::Data: { 1548 return OpenACCDataConstruct::Create( 1549 getASTContext(), StartLoc, DirLoc, EndLoc, Clauses, 1550 AssocStmt.isUsable() ? AssocStmt.get() : nullptr); 1551 } 1552 case OpenACCDirectiveKind::EnterData: { 1553 return OpenACCEnterDataConstruct::Create(getASTContext(), StartLoc, DirLoc, 1554 EndLoc, Clauses); 1555 } 1556 case OpenACCDirectiveKind::ExitData: { 1557 return OpenACCExitDataConstruct::Create(getASTContext(), StartLoc, DirLoc, 1558 EndLoc, Clauses); 1559 } 1560 case OpenACCDirectiveKind::HostData: { 1561 return OpenACCHostDataConstruct::Create( 1562 getASTContext(), StartLoc, DirLoc, EndLoc, Clauses, 1563 AssocStmt.isUsable() ? AssocStmt.get() : nullptr); 1564 } 1565 case OpenACCDirectiveKind::Wait: { 1566 return OpenACCWaitConstruct::Create( 1567 getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc, 1568 Exprs.drop_front(), RParenLoc, EndLoc, Clauses); 1569 } 1570 case OpenACCDirectiveKind::Init: { 1571 return OpenACCInitConstruct::Create(getASTContext(), StartLoc, DirLoc, 1572 EndLoc, Clauses); 1573 } 1574 case OpenACCDirectiveKind::Shutdown: { 1575 return OpenACCShutdownConstruct::Create(getASTContext(), StartLoc, DirLoc, 1576 EndLoc, Clauses); 1577 } 1578 case OpenACCDirectiveKind::Set: { 1579 return OpenACCSetConstruct::Create(getASTContext(), StartLoc, DirLoc, 1580 EndLoc, Clauses); 1581 } 1582 case OpenACCDirectiveKind::Update: { 1583 return OpenACCUpdateConstruct::Create(getASTContext(), StartLoc, DirLoc, 1584 EndLoc, Clauses); 1585 } 1586 } 1587 llvm_unreachable("Unhandled case in directive handling?"); 1588 } 1589 1590 StmtResult SemaOpenACC::ActOnAssociatedStmt( 1591 SourceLocation DirectiveLoc, OpenACCDirectiveKind K, 1592 ArrayRef<const OpenACCClause *> Clauses, StmtResult AssocStmt) { 1593 switch (K) { 1594 default: 1595 llvm_unreachable("Unimplemented associated statement application"); 1596 case OpenACCDirectiveKind::EnterData: 1597 case OpenACCDirectiveKind::ExitData: 1598 case OpenACCDirectiveKind::Wait: 1599 case OpenACCDirectiveKind::Init: 1600 case OpenACCDirectiveKind::Shutdown: 1601 case OpenACCDirectiveKind::Set: 1602 llvm_unreachable( 1603 "these don't have associated statements, so shouldn't get here"); 1604 case OpenACCDirectiveKind::Parallel: 1605 case OpenACCDirectiveKind::Serial: 1606 case OpenACCDirectiveKind::Kernels: 1607 case OpenACCDirectiveKind::Data: 1608 case OpenACCDirectiveKind::HostData: 1609 // There really isn't any checking here that could happen. As long as we 1610 // have a statement to associate, this should be fine. 1611 // OpenACC 3.3 Section 6: 1612 // Structured Block: in C or C++, an executable statement, possibly 1613 // compound, with a single entry at the top and a single exit at the 1614 // bottom. 1615 // FIXME: Should we reject DeclStmt's here? The standard isn't clear, and 1616 // an interpretation of it is to allow this and treat the initializer as 1617 // the 'structured block'. 1618 return AssocStmt; 1619 case OpenACCDirectiveKind::Loop: 1620 case OpenACCDirectiveKind::ParallelLoop: 1621 case OpenACCDirectiveKind::SerialLoop: 1622 case OpenACCDirectiveKind::KernelsLoop: 1623 if (!AssocStmt.isUsable()) 1624 return StmtError(); 1625 1626 if (!isa<CXXForRangeStmt, ForStmt>(AssocStmt.get())) { 1627 Diag(AssocStmt.get()->getBeginLoc(), diag::err_acc_loop_not_for_loop) 1628 << K; 1629 Diag(DirectiveLoc, diag::note_acc_construct_here) << K; 1630 return StmtError(); 1631 } 1632 1633 if (!CollapseInfo.CollapseDepthSatisfied || !TileInfo.TileDepthSatisfied) { 1634 if (!CollapseInfo.CollapseDepthSatisfied) { 1635 Diag(DirectiveLoc, diag::err_acc_insufficient_loops) 1636 << OpenACCClauseKind::Collapse; 1637 assert(CollapseInfo.ActiveCollapse && "Collapse count without object?"); 1638 Diag(CollapseInfo.ActiveCollapse->getBeginLoc(), 1639 diag::note_acc_active_clause_here) 1640 << OpenACCClauseKind::Collapse; 1641 } 1642 1643 if (!TileInfo.TileDepthSatisfied) { 1644 Diag(DirectiveLoc, diag::err_acc_insufficient_loops) 1645 << OpenACCClauseKind::Tile; 1646 assert(TileInfo.ActiveTile && "Collapse count without object?"); 1647 Diag(TileInfo.ActiveTile->getBeginLoc(), 1648 diag::note_acc_active_clause_here) 1649 << OpenACCClauseKind::Tile; 1650 } 1651 return StmtError(); 1652 } 1653 1654 return AssocStmt.get(); 1655 } 1656 llvm_unreachable("Invalid associated statement application"); 1657 } 1658 1659 bool SemaOpenACC::ActOnStartDeclDirective(OpenACCDirectiveKind K, 1660 SourceLocation StartLoc) { 1661 // OpenCC3.3 2.1 (line 889) 1662 // A program must not depend on the order of evaluation of expressions in 1663 // clause arguments or on any side effects of the evaluations. 1664 SemaRef.DiscardCleanupsInEvaluationContext(); 1665 SemaRef.PopExpressionEvaluationContext(); 1666 return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false); 1667 } 1668 1669 DeclGroupRef SemaOpenACC::ActOnEndDeclDirective() { return DeclGroupRef{}; } 1670 1671 ExprResult 1672 SemaOpenACC::BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) { 1673 return OpenACCAsteriskSizeExpr::Create(getASTContext(), AsteriskLoc); 1674 } 1675 1676 ExprResult 1677 SemaOpenACC::ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) { 1678 return BuildOpenACCAsteriskSizeExpr(AsteriskLoc); 1679 } 1680