xref: /freebsd/contrib/llvm-project/clang/lib/AST/StmtOpenACC.cpp (revision 5036d9652a5701d00e9e40ea942c278e9f77d33d)
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