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 *
CreateEmpty(const ASTContext & C,unsigned NumClauses)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
Create(const ASTContext & C,OpenACCDirectiveKind K,SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<const OpenACCClause * > Clauses,Stmt * StructuredBlock,ArrayRef<OpenACCLoopConstruct * > AssociatedLoopConstructs)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
findAndSetChildLoops()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
OpenACCLoopConstruct(unsigned NumClauses)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
OpenACCLoopConstruct(SourceLocation Start,SourceLocation DirLoc,SourceLocation End,ArrayRef<const OpenACCClause * > Clauses,Stmt * Loop)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
setLoop(Stmt * Loop)99 void OpenACCLoopConstruct::setLoop(Stmt *Loop) {
100 assert((isa<ForStmt, CXXForRangeStmt>(Loop)) &&
101 "Associated Loop not a for loop?");
102 setAssociatedStmt(Loop);
103 }
104
CreateEmpty(const ASTContext & C,unsigned NumClauses)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 *
Create(const ASTContext & C,SourceLocation BeginLoc,SourceLocation DirLoc,SourceLocation EndLoc,ArrayRef<const OpenACCClause * > Clauses,Stmt * Loop)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