1 //===---- OpenACCClause.cpp - Classes for OpenACC Clauses ----------------===// 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 // 9 // This file implements the subclasses of the OpenACCClause class declared in 10 // OpenACCClause.h 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/OpenACCClause.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/Expr.h" 17 18 using namespace clang; 19 20 bool OpenACCClauseWithParams::classof(const OpenACCClause *C) { 21 return OpenACCDeviceTypeClause::classof(C) || 22 OpenACCClauseWithCondition::classof(C) || 23 OpenACCClauseWithExprs::classof(C); 24 } 25 bool OpenACCClauseWithExprs::classof(const OpenACCClause *C) { 26 return OpenACCWaitClause::classof(C) || OpenACCNumGangsClause::classof(C) || 27 OpenACCClauseWithSingleIntExpr::classof(C) || 28 OpenACCClauseWithVarList::classof(C); 29 } 30 bool OpenACCClauseWithVarList::classof(const OpenACCClause *C) { 31 return OpenACCPrivateClause::classof(C) || 32 OpenACCFirstPrivateClause::classof(C) || 33 OpenACCDevicePtrClause::classof(C) || 34 OpenACCDevicePtrClause::classof(C) || 35 OpenACCAttachClause::classof(C) || OpenACCNoCreateClause::classof(C) || 36 OpenACCPresentClause::classof(C) || OpenACCCopyClause::classof(C) || 37 OpenACCCopyInClause::classof(C) || OpenACCCopyOutClause::classof(C) || 38 OpenACCReductionClause::classof(C) || OpenACCCreateClause::classof(C); 39 } 40 bool OpenACCClauseWithCondition::classof(const OpenACCClause *C) { 41 return OpenACCIfClause::classof(C) || OpenACCSelfClause::classof(C); 42 } 43 bool OpenACCClauseWithSingleIntExpr::classof(const OpenACCClause *C) { 44 return OpenACCNumWorkersClause::classof(C) || 45 OpenACCVectorLengthClause::classof(C) || 46 OpenACCAsyncClause::classof(C); 47 } 48 OpenACCDefaultClause *OpenACCDefaultClause::Create(const ASTContext &C, 49 OpenACCDefaultClauseKind K, 50 SourceLocation BeginLoc, 51 SourceLocation LParenLoc, 52 SourceLocation EndLoc) { 53 void *Mem = 54 C.Allocate(sizeof(OpenACCDefaultClause), alignof(OpenACCDefaultClause)); 55 56 return new (Mem) OpenACCDefaultClause(K, BeginLoc, LParenLoc, EndLoc); 57 } 58 59 OpenACCIfClause *OpenACCIfClause::Create(const ASTContext &C, 60 SourceLocation BeginLoc, 61 SourceLocation LParenLoc, 62 Expr *ConditionExpr, 63 SourceLocation EndLoc) { 64 void *Mem = C.Allocate(sizeof(OpenACCIfClause), alignof(OpenACCIfClause)); 65 return new (Mem) OpenACCIfClause(BeginLoc, LParenLoc, ConditionExpr, EndLoc); 66 } 67 68 OpenACCIfClause::OpenACCIfClause(SourceLocation BeginLoc, 69 SourceLocation LParenLoc, Expr *ConditionExpr, 70 SourceLocation EndLoc) 71 : OpenACCClauseWithCondition(OpenACCClauseKind::If, BeginLoc, LParenLoc, 72 ConditionExpr, EndLoc) { 73 assert(ConditionExpr && "if clause requires condition expr"); 74 assert((ConditionExpr->isInstantiationDependent() || 75 ConditionExpr->getType()->isScalarType()) && 76 "Condition expression type not scalar/dependent"); 77 } 78 79 OpenACCSelfClause *OpenACCSelfClause::Create(const ASTContext &C, 80 SourceLocation BeginLoc, 81 SourceLocation LParenLoc, 82 Expr *ConditionExpr, 83 SourceLocation EndLoc) { 84 void *Mem = C.Allocate(sizeof(OpenACCIfClause), alignof(OpenACCIfClause)); 85 return new (Mem) 86 OpenACCSelfClause(BeginLoc, LParenLoc, ConditionExpr, EndLoc); 87 } 88 89 OpenACCSelfClause::OpenACCSelfClause(SourceLocation BeginLoc, 90 SourceLocation LParenLoc, 91 Expr *ConditionExpr, SourceLocation EndLoc) 92 : OpenACCClauseWithCondition(OpenACCClauseKind::Self, BeginLoc, LParenLoc, 93 ConditionExpr, EndLoc) { 94 assert((!ConditionExpr || ConditionExpr->isInstantiationDependent() || 95 ConditionExpr->getType()->isScalarType()) && 96 "Condition expression type not scalar/dependent"); 97 } 98 99 OpenACCClause::child_range OpenACCClause::children() { 100 switch (getClauseKind()) { 101 default: 102 assert(false && "Clause children function not implemented"); 103 break; 104 #define VISIT_CLAUSE(CLAUSE_NAME) \ 105 case OpenACCClauseKind::CLAUSE_NAME: \ 106 return cast<OpenACC##CLAUSE_NAME##Clause>(this)->children(); 107 #define CLAUSE_ALIAS(ALIAS_NAME, CLAUSE_NAME, DEPRECATED) \ 108 case OpenACCClauseKind::ALIAS_NAME: \ 109 return cast<OpenACC##CLAUSE_NAME##Clause>(this)->children(); 110 111 #include "clang/Basic/OpenACCClauses.def" 112 } 113 return child_range(child_iterator(), child_iterator()); 114 } 115 116 OpenACCNumWorkersClause::OpenACCNumWorkersClause(SourceLocation BeginLoc, 117 SourceLocation LParenLoc, 118 Expr *IntExpr, 119 SourceLocation EndLoc) 120 : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::NumWorkers, BeginLoc, 121 LParenLoc, IntExpr, EndLoc) { 122 assert((!IntExpr || IntExpr->isInstantiationDependent() || 123 IntExpr->getType()->isIntegerType()) && 124 "Condition expression type not scalar/dependent"); 125 } 126 127 OpenACCNumWorkersClause * 128 OpenACCNumWorkersClause::Create(const ASTContext &C, SourceLocation BeginLoc, 129 SourceLocation LParenLoc, Expr *IntExpr, 130 SourceLocation EndLoc) { 131 void *Mem = C.Allocate(sizeof(OpenACCNumWorkersClause), 132 alignof(OpenACCNumWorkersClause)); 133 return new (Mem) 134 OpenACCNumWorkersClause(BeginLoc, LParenLoc, IntExpr, EndLoc); 135 } 136 137 OpenACCVectorLengthClause::OpenACCVectorLengthClause(SourceLocation BeginLoc, 138 SourceLocation LParenLoc, 139 Expr *IntExpr, 140 SourceLocation EndLoc) 141 : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::VectorLength, BeginLoc, 142 LParenLoc, IntExpr, EndLoc) { 143 assert((!IntExpr || IntExpr->isInstantiationDependent() || 144 IntExpr->getType()->isIntegerType()) && 145 "Condition expression type not scalar/dependent"); 146 } 147 148 OpenACCVectorLengthClause * 149 OpenACCVectorLengthClause::Create(const ASTContext &C, SourceLocation BeginLoc, 150 SourceLocation LParenLoc, Expr *IntExpr, 151 SourceLocation EndLoc) { 152 void *Mem = C.Allocate(sizeof(OpenACCVectorLengthClause), 153 alignof(OpenACCVectorLengthClause)); 154 return new (Mem) 155 OpenACCVectorLengthClause(BeginLoc, LParenLoc, IntExpr, EndLoc); 156 } 157 158 OpenACCAsyncClause::OpenACCAsyncClause(SourceLocation BeginLoc, 159 SourceLocation LParenLoc, Expr *IntExpr, 160 SourceLocation EndLoc) 161 : OpenACCClauseWithSingleIntExpr(OpenACCClauseKind::Async, BeginLoc, 162 LParenLoc, IntExpr, EndLoc) { 163 assert((!IntExpr || IntExpr->isInstantiationDependent() || 164 IntExpr->getType()->isIntegerType()) && 165 "Condition expression type not scalar/dependent"); 166 } 167 168 OpenACCAsyncClause *OpenACCAsyncClause::Create(const ASTContext &C, 169 SourceLocation BeginLoc, 170 SourceLocation LParenLoc, 171 Expr *IntExpr, 172 SourceLocation EndLoc) { 173 void *Mem = 174 C.Allocate(sizeof(OpenACCAsyncClause), alignof(OpenACCAsyncClause)); 175 return new (Mem) OpenACCAsyncClause(BeginLoc, LParenLoc, IntExpr, EndLoc); 176 } 177 178 OpenACCWaitClause *OpenACCWaitClause::Create( 179 const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 180 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs, 181 SourceLocation EndLoc) { 182 // Allocates enough room in trailing storage for all the int-exprs, plus a 183 // placeholder for the devnum. 184 void *Mem = C.Allocate( 185 OpenACCWaitClause::totalSizeToAlloc<Expr *>(QueueIdExprs.size() + 1)); 186 return new (Mem) OpenACCWaitClause(BeginLoc, LParenLoc, DevNumExpr, QueuesLoc, 187 QueueIdExprs, EndLoc); 188 } 189 190 OpenACCNumGangsClause *OpenACCNumGangsClause::Create(const ASTContext &C, 191 SourceLocation BeginLoc, 192 SourceLocation LParenLoc, 193 ArrayRef<Expr *> IntExprs, 194 SourceLocation EndLoc) { 195 void *Mem = C.Allocate( 196 OpenACCNumGangsClause::totalSizeToAlloc<Expr *>(IntExprs.size())); 197 return new (Mem) OpenACCNumGangsClause(BeginLoc, LParenLoc, IntExprs, EndLoc); 198 } 199 200 OpenACCPrivateClause *OpenACCPrivateClause::Create(const ASTContext &C, 201 SourceLocation BeginLoc, 202 SourceLocation LParenLoc, 203 ArrayRef<Expr *> VarList, 204 SourceLocation EndLoc) { 205 void *Mem = C.Allocate( 206 OpenACCPrivateClause::totalSizeToAlloc<Expr *>(VarList.size())); 207 return new (Mem) OpenACCPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc); 208 } 209 210 OpenACCFirstPrivateClause *OpenACCFirstPrivateClause::Create( 211 const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 212 ArrayRef<Expr *> VarList, SourceLocation EndLoc) { 213 void *Mem = C.Allocate( 214 OpenACCFirstPrivateClause::totalSizeToAlloc<Expr *>(VarList.size())); 215 return new (Mem) 216 OpenACCFirstPrivateClause(BeginLoc, LParenLoc, VarList, EndLoc); 217 } 218 219 OpenACCAttachClause *OpenACCAttachClause::Create(const ASTContext &C, 220 SourceLocation BeginLoc, 221 SourceLocation LParenLoc, 222 ArrayRef<Expr *> VarList, 223 SourceLocation EndLoc) { 224 void *Mem = 225 C.Allocate(OpenACCAttachClause::totalSizeToAlloc<Expr *>(VarList.size())); 226 return new (Mem) OpenACCAttachClause(BeginLoc, LParenLoc, VarList, EndLoc); 227 } 228 229 OpenACCDevicePtrClause *OpenACCDevicePtrClause::Create(const ASTContext &C, 230 SourceLocation BeginLoc, 231 SourceLocation LParenLoc, 232 ArrayRef<Expr *> VarList, 233 SourceLocation EndLoc) { 234 void *Mem = C.Allocate( 235 OpenACCDevicePtrClause::totalSizeToAlloc<Expr *>(VarList.size())); 236 return new (Mem) OpenACCDevicePtrClause(BeginLoc, LParenLoc, VarList, EndLoc); 237 } 238 239 OpenACCNoCreateClause *OpenACCNoCreateClause::Create(const ASTContext &C, 240 SourceLocation BeginLoc, 241 SourceLocation LParenLoc, 242 ArrayRef<Expr *> VarList, 243 SourceLocation EndLoc) { 244 void *Mem = C.Allocate( 245 OpenACCNoCreateClause::totalSizeToAlloc<Expr *>(VarList.size())); 246 return new (Mem) OpenACCNoCreateClause(BeginLoc, LParenLoc, VarList, EndLoc); 247 } 248 249 OpenACCPresentClause *OpenACCPresentClause::Create(const ASTContext &C, 250 SourceLocation BeginLoc, 251 SourceLocation LParenLoc, 252 ArrayRef<Expr *> VarList, 253 SourceLocation EndLoc) { 254 void *Mem = C.Allocate( 255 OpenACCPresentClause::totalSizeToAlloc<Expr *>(VarList.size())); 256 return new (Mem) OpenACCPresentClause(BeginLoc, LParenLoc, VarList, EndLoc); 257 } 258 259 OpenACCCopyClause * 260 OpenACCCopyClause::Create(const ASTContext &C, OpenACCClauseKind Spelling, 261 SourceLocation BeginLoc, SourceLocation LParenLoc, 262 ArrayRef<Expr *> VarList, SourceLocation EndLoc) { 263 void *Mem = 264 C.Allocate(OpenACCCopyClause::totalSizeToAlloc<Expr *>(VarList.size())); 265 return new (Mem) 266 OpenACCCopyClause(Spelling, BeginLoc, LParenLoc, VarList, EndLoc); 267 } 268 269 OpenACCCopyInClause * 270 OpenACCCopyInClause::Create(const ASTContext &C, OpenACCClauseKind Spelling, 271 SourceLocation BeginLoc, SourceLocation LParenLoc, 272 bool IsReadOnly, ArrayRef<Expr *> VarList, 273 SourceLocation EndLoc) { 274 void *Mem = 275 C.Allocate(OpenACCCopyInClause::totalSizeToAlloc<Expr *>(VarList.size())); 276 return new (Mem) OpenACCCopyInClause(Spelling, BeginLoc, LParenLoc, 277 IsReadOnly, VarList, EndLoc); 278 } 279 280 OpenACCCopyOutClause * 281 OpenACCCopyOutClause::Create(const ASTContext &C, OpenACCClauseKind Spelling, 282 SourceLocation BeginLoc, SourceLocation LParenLoc, 283 bool IsZero, ArrayRef<Expr *> VarList, 284 SourceLocation EndLoc) { 285 void *Mem = C.Allocate( 286 OpenACCCopyOutClause::totalSizeToAlloc<Expr *>(VarList.size())); 287 return new (Mem) OpenACCCopyOutClause(Spelling, BeginLoc, LParenLoc, IsZero, 288 VarList, EndLoc); 289 } 290 291 OpenACCCreateClause * 292 OpenACCCreateClause::Create(const ASTContext &C, OpenACCClauseKind Spelling, 293 SourceLocation BeginLoc, SourceLocation LParenLoc, 294 bool IsZero, ArrayRef<Expr *> VarList, 295 SourceLocation EndLoc) { 296 void *Mem = 297 C.Allocate(OpenACCCreateClause::totalSizeToAlloc<Expr *>(VarList.size())); 298 return new (Mem) OpenACCCreateClause(Spelling, BeginLoc, LParenLoc, IsZero, 299 VarList, EndLoc); 300 } 301 302 OpenACCDeviceTypeClause *OpenACCDeviceTypeClause::Create( 303 const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc, 304 SourceLocation LParenLoc, ArrayRef<DeviceTypeArgument> Archs, 305 SourceLocation EndLoc) { 306 void *Mem = 307 C.Allocate(OpenACCDeviceTypeClause::totalSizeToAlloc<DeviceTypeArgument>( 308 Archs.size())); 309 return new (Mem) 310 OpenACCDeviceTypeClause(K, BeginLoc, LParenLoc, Archs, EndLoc); 311 } 312 313 OpenACCReductionClause *OpenACCReductionClause::Create( 314 const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, 315 OpenACCReductionOperator Operator, ArrayRef<Expr *> VarList, 316 SourceLocation EndLoc) { 317 void *Mem = C.Allocate( 318 OpenACCReductionClause::totalSizeToAlloc<Expr *>(VarList.size())); 319 return new (Mem) 320 OpenACCReductionClause(BeginLoc, LParenLoc, Operator, VarList, EndLoc); 321 } 322 323 OpenACCAutoClause *OpenACCAutoClause::Create(const ASTContext &C, 324 SourceLocation BeginLoc, 325 SourceLocation EndLoc) { 326 void *Mem = C.Allocate(sizeof(OpenACCAutoClause)); 327 return new (Mem) OpenACCAutoClause(BeginLoc, EndLoc); 328 } 329 330 OpenACCIndependentClause * 331 OpenACCIndependentClause::Create(const ASTContext &C, SourceLocation BeginLoc, 332 SourceLocation EndLoc) { 333 void *Mem = C.Allocate(sizeof(OpenACCIndependentClause)); 334 return new (Mem) OpenACCIndependentClause(BeginLoc, EndLoc); 335 } 336 337 OpenACCSeqClause *OpenACCSeqClause::Create(const ASTContext &C, 338 SourceLocation BeginLoc, 339 SourceLocation EndLoc) { 340 void *Mem = C.Allocate(sizeof(OpenACCSeqClause)); 341 return new (Mem) OpenACCSeqClause(BeginLoc, EndLoc); 342 } 343 344 OpenACCGangClause *OpenACCGangClause::Create(const ASTContext &C, 345 SourceLocation BeginLoc, 346 SourceLocation EndLoc) { 347 void *Mem = C.Allocate(sizeof(OpenACCGangClause)); 348 return new (Mem) OpenACCGangClause(BeginLoc, EndLoc); 349 } 350 351 OpenACCWorkerClause *OpenACCWorkerClause::Create(const ASTContext &C, 352 SourceLocation BeginLoc, 353 SourceLocation EndLoc) { 354 void *Mem = C.Allocate(sizeof(OpenACCWorkerClause)); 355 return new (Mem) OpenACCWorkerClause(BeginLoc, EndLoc); 356 } 357 358 OpenACCVectorClause *OpenACCVectorClause::Create(const ASTContext &C, 359 SourceLocation BeginLoc, 360 SourceLocation EndLoc) { 361 void *Mem = C.Allocate(sizeof(OpenACCVectorClause)); 362 return new (Mem) OpenACCVectorClause(BeginLoc, EndLoc); 363 } 364 365 //===----------------------------------------------------------------------===// 366 // OpenACC clauses printing methods 367 //===----------------------------------------------------------------------===// 368 369 void OpenACCClausePrinter::printExpr(const Expr *E) { 370 E->printPretty(OS, nullptr, Policy, 0); 371 } 372 373 void OpenACCClausePrinter::VisitDefaultClause(const OpenACCDefaultClause &C) { 374 OS << "default(" << C.getDefaultClauseKind() << ")"; 375 } 376 377 void OpenACCClausePrinter::VisitIfClause(const OpenACCIfClause &C) { 378 OS << "if("; 379 printExpr(C.getConditionExpr()); 380 OS << ")"; 381 } 382 383 void OpenACCClausePrinter::VisitSelfClause(const OpenACCSelfClause &C) { 384 OS << "self"; 385 if (const Expr *CondExpr = C.getConditionExpr()) { 386 OS << "("; 387 printExpr(CondExpr); 388 OS << ")"; 389 } 390 } 391 392 void OpenACCClausePrinter::VisitNumGangsClause(const OpenACCNumGangsClause &C) { 393 OS << "num_gangs("; 394 llvm::interleaveComma(C.getIntExprs(), OS, 395 [&](const Expr *E) { printExpr(E); }); 396 OS << ")"; 397 } 398 399 void OpenACCClausePrinter::VisitNumWorkersClause( 400 const OpenACCNumWorkersClause &C) { 401 OS << "num_workers("; 402 printExpr(C.getIntExpr()); 403 OS << ")"; 404 } 405 406 void OpenACCClausePrinter::VisitVectorLengthClause( 407 const OpenACCVectorLengthClause &C) { 408 OS << "vector_length("; 409 printExpr(C.getIntExpr()); 410 OS << ")"; 411 } 412 413 void OpenACCClausePrinter::VisitAsyncClause(const OpenACCAsyncClause &C) { 414 OS << "async"; 415 if (C.hasIntExpr()) { 416 OS << "("; 417 printExpr(C.getIntExpr()); 418 OS << ")"; 419 } 420 } 421 422 void OpenACCClausePrinter::VisitPrivateClause(const OpenACCPrivateClause &C) { 423 OS << "private("; 424 llvm::interleaveComma(C.getVarList(), OS, 425 [&](const Expr *E) { printExpr(E); }); 426 OS << ")"; 427 } 428 429 void OpenACCClausePrinter::VisitFirstPrivateClause( 430 const OpenACCFirstPrivateClause &C) { 431 OS << "firstprivate("; 432 llvm::interleaveComma(C.getVarList(), OS, 433 [&](const Expr *E) { printExpr(E); }); 434 OS << ")"; 435 } 436 437 void OpenACCClausePrinter::VisitAttachClause(const OpenACCAttachClause &C) { 438 OS << "attach("; 439 llvm::interleaveComma(C.getVarList(), OS, 440 [&](const Expr *E) { printExpr(E); }); 441 OS << ")"; 442 } 443 444 void OpenACCClausePrinter::VisitDevicePtrClause( 445 const OpenACCDevicePtrClause &C) { 446 OS << "deviceptr("; 447 llvm::interleaveComma(C.getVarList(), OS, 448 [&](const Expr *E) { printExpr(E); }); 449 OS << ")"; 450 } 451 452 void OpenACCClausePrinter::VisitNoCreateClause(const OpenACCNoCreateClause &C) { 453 OS << "no_create("; 454 llvm::interleaveComma(C.getVarList(), OS, 455 [&](const Expr *E) { printExpr(E); }); 456 OS << ")"; 457 } 458 459 void OpenACCClausePrinter::VisitPresentClause(const OpenACCPresentClause &C) { 460 OS << "present("; 461 llvm::interleaveComma(C.getVarList(), OS, 462 [&](const Expr *E) { printExpr(E); }); 463 OS << ")"; 464 } 465 466 void OpenACCClausePrinter::VisitCopyClause(const OpenACCCopyClause &C) { 467 OS << C.getClauseKind() << '('; 468 llvm::interleaveComma(C.getVarList(), OS, 469 [&](const Expr *E) { printExpr(E); }); 470 OS << ")"; 471 } 472 473 void OpenACCClausePrinter::VisitCopyInClause(const OpenACCCopyInClause &C) { 474 OS << C.getClauseKind() << '('; 475 if (C.isReadOnly()) 476 OS << "readonly: "; 477 llvm::interleaveComma(C.getVarList(), OS, 478 [&](const Expr *E) { printExpr(E); }); 479 OS << ")"; 480 } 481 482 void OpenACCClausePrinter::VisitCopyOutClause(const OpenACCCopyOutClause &C) { 483 OS << C.getClauseKind() << '('; 484 if (C.isZero()) 485 OS << "zero: "; 486 llvm::interleaveComma(C.getVarList(), OS, 487 [&](const Expr *E) { printExpr(E); }); 488 OS << ")"; 489 } 490 491 void OpenACCClausePrinter::VisitCreateClause(const OpenACCCreateClause &C) { 492 OS << C.getClauseKind() << '('; 493 if (C.isZero()) 494 OS << "zero: "; 495 llvm::interleaveComma(C.getVarList(), OS, 496 [&](const Expr *E) { printExpr(E); }); 497 OS << ")"; 498 } 499 500 void OpenACCClausePrinter::VisitReductionClause( 501 const OpenACCReductionClause &C) { 502 OS << "reduction(" << C.getReductionOp() << ": "; 503 llvm::interleaveComma(C.getVarList(), OS, 504 [&](const Expr *E) { printExpr(E); }); 505 OS << ")"; 506 } 507 508 void OpenACCClausePrinter::VisitWaitClause(const OpenACCWaitClause &C) { 509 OS << "wait"; 510 if (!C.getLParenLoc().isInvalid()) { 511 OS << "("; 512 if (C.hasDevNumExpr()) { 513 OS << "devnum: "; 514 printExpr(C.getDevNumExpr()); 515 OS << " : "; 516 } 517 518 if (C.hasQueuesTag()) 519 OS << "queues: "; 520 521 llvm::interleaveComma(C.getQueueIdExprs(), OS, 522 [&](const Expr *E) { printExpr(E); }); 523 OS << ")"; 524 } 525 } 526 527 void OpenACCClausePrinter::VisitDeviceTypeClause( 528 const OpenACCDeviceTypeClause &C) { 529 OS << C.getClauseKind(); 530 OS << "("; 531 llvm::interleaveComma(C.getArchitectures(), OS, 532 [&](const DeviceTypeArgument &Arch) { 533 if (Arch.first == nullptr) 534 OS << "*"; 535 else 536 OS << Arch.first->getName(); 537 }); 538 OS << ")"; 539 } 540 541 void OpenACCClausePrinter::VisitAutoClause(const OpenACCAutoClause &C) { 542 OS << "auto"; 543 } 544 545 void OpenACCClausePrinter::VisitIndependentClause( 546 const OpenACCIndependentClause &C) { 547 OS << "independent"; 548 } 549 550 void OpenACCClausePrinter::VisitSeqClause(const OpenACCSeqClause &C) { 551 OS << "seq"; 552 } 553