1 //===--- StmtOpenACC.cpp - Classes 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 // 9 // This file implements the subclasses of Stmt class declared in StmtOpenACC.h 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/AST/StmtOpenACC.h" 14 #include "clang/AST/ASTContext.h" 15 #include "clang/AST/RecursiveASTVisitor.h" 16 #include "clang/AST/StmtCXX.h" 17 using namespace clang; 18 19 OpenACCComputeConstruct * 20 OpenACCComputeConstruct::CreateEmpty(const ASTContext &C, unsigned NumClauses) { 21 void *Mem = C.Allocate( 22 OpenACCComputeConstruct::totalSizeToAlloc<const OpenACCClause *>( 23 NumClauses)); 24 auto *Inst = new (Mem) OpenACCComputeConstruct(NumClauses); 25 return Inst; 26 } 27 28 OpenACCComputeConstruct *OpenACCComputeConstruct::Create( 29 const ASTContext &C, OpenACCDirectiveKind K, SourceLocation BeginLoc, 30 SourceLocation DirLoc, SourceLocation EndLoc, 31 ArrayRef<const OpenACCClause *> Clauses, Stmt *StructuredBlock, 32 ArrayRef<OpenACCLoopConstruct *> AssociatedLoopConstructs) { 33 void *Mem = C.Allocate( 34 OpenACCComputeConstruct::totalSizeToAlloc<const OpenACCClause *>( 35 Clauses.size())); 36 auto *Inst = new (Mem) OpenACCComputeConstruct(K, BeginLoc, DirLoc, EndLoc, 37 Clauses, StructuredBlock); 38 39 llvm::for_each(AssociatedLoopConstructs, [&](OpenACCLoopConstruct *C) { 40 C->setParentComputeConstruct(Inst); 41 }); 42 43 return Inst; 44 } 45 46 void OpenACCComputeConstruct::findAndSetChildLoops() { 47 struct LoopConstructFinder : RecursiveASTVisitor<LoopConstructFinder> { 48 OpenACCComputeConstruct *Construct = nullptr; 49 50 LoopConstructFinder(OpenACCComputeConstruct *Construct) 51 : Construct(Construct) {} 52 53 bool TraverseOpenACCComputeConstruct(OpenACCComputeConstruct *C) { 54 // Stop searching if we find a compute construct. 55 return true; 56 } 57 bool TraverseOpenACCLoopConstruct(OpenACCLoopConstruct *C) { 58 // Stop searching if we find a loop construct, after taking ownership of 59 // it. 60 C->setParentComputeConstruct(Construct); 61 return true; 62 } 63 }; 64 65 LoopConstructFinder f(this); 66 f.TraverseStmt(getAssociatedStmt()); 67 } 68 69 OpenACCLoopConstruct::OpenACCLoopConstruct(unsigned NumClauses) 70 : OpenACCAssociatedStmtConstruct( 71 OpenACCLoopConstructClass, OpenACCDirectiveKind::Loop, 72 SourceLocation{}, SourceLocation{}, SourceLocation{}, 73 /*AssociatedStmt=*/nullptr) { 74 std::uninitialized_value_construct( 75 getTrailingObjects<const OpenACCClause *>(), 76 getTrailingObjects<const OpenACCClause *>() + NumClauses); 77 setClauseList( 78 MutableArrayRef(getTrailingObjects<const OpenACCClause *>(), NumClauses)); 79 } 80 81 OpenACCLoopConstruct::OpenACCLoopConstruct( 82 SourceLocation Start, SourceLocation DirLoc, SourceLocation End, 83 ArrayRef<const OpenACCClause *> Clauses, Stmt *Loop) 84 : OpenACCAssociatedStmtConstruct(OpenACCLoopConstructClass, 85 OpenACCDirectiveKind::Loop, Start, DirLoc, 86 End, Loop) { 87 // accept 'nullptr' for the loop. This is diagnosed somewhere, but this gives 88 // us some level of AST fidelity in the error case. 89 assert((Loop == nullptr || isa<ForStmt, CXXForRangeStmt>(Loop)) && 90 "Associated Loop not a for loop?"); 91 // Initialize the trailing storage. 92 std::uninitialized_copy(Clauses.begin(), Clauses.end(), 93 getTrailingObjects<const OpenACCClause *>()); 94 95 setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(), 96 Clauses.size())); 97 } 98 99 void OpenACCLoopConstruct::setLoop(Stmt *Loop) { 100 assert((isa<ForStmt, CXXForRangeStmt>(Loop)) && 101 "Associated Loop not a for loop?"); 102 setAssociatedStmt(Loop); 103 } 104 105 OpenACCLoopConstruct *OpenACCLoopConstruct::CreateEmpty(const ASTContext &C, 106 unsigned NumClauses) { 107 void *Mem = 108 C.Allocate(OpenACCLoopConstruct::totalSizeToAlloc<const OpenACCClause *>( 109 NumClauses)); 110 auto *Inst = new (Mem) OpenACCLoopConstruct(NumClauses); 111 return Inst; 112 } 113 114 OpenACCLoopConstruct * 115 OpenACCLoopConstruct::Create(const ASTContext &C, SourceLocation BeginLoc, 116 SourceLocation DirLoc, SourceLocation EndLoc, 117 ArrayRef<const OpenACCClause *> Clauses, 118 Stmt *Loop) { 119 void *Mem = 120 C.Allocate(OpenACCLoopConstruct::totalSizeToAlloc<const OpenACCClause *>( 121 Clauses.size())); 122 auto *Inst = 123 new (Mem) OpenACCLoopConstruct(BeginLoc, DirLoc, EndLoc, Clauses, Loop); 124 return Inst; 125 } 126