1 //===--- DeclOpenMP.cpp - Declaration OpenMP AST Node Implementation ------===//
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 OMPThreadPrivateDecl, OMPCapturedExprDecl
10 /// classes.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclBase.h"
17 #include "clang/AST/DeclOpenMP.h"
18 #include "clang/AST/Expr.h"
19 
20 using namespace clang;
21 
22 //===----------------------------------------------------------------------===//
23 // OMPThreadPrivateDecl Implementation.
24 //===----------------------------------------------------------------------===//
25 
26 void OMPThreadPrivateDecl::anchor() { }
27 
28 OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C,
29                                                    DeclContext *DC,
30                                                    SourceLocation L,
31                                                    ArrayRef<Expr *> VL) {
32   OMPThreadPrivateDecl *D =
33       new (C, DC, additionalSizeToAlloc<Expr *>(VL.size()))
34           OMPThreadPrivateDecl(OMPThreadPrivate, DC, L);
35   D->NumVars = VL.size();
36   D->setVars(VL);
37   return D;
38 }
39 
40 OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C,
41                                                                unsigned ID,
42                                                                unsigned N) {
43   OMPThreadPrivateDecl *D = new (C, ID, additionalSizeToAlloc<Expr *>(N))
44       OMPThreadPrivateDecl(OMPThreadPrivate, nullptr, SourceLocation());
45   D->NumVars = N;
46   return D;
47 }
48 
49 void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) {
50   assert(VL.size() == NumVars &&
51          "Number of variables is not the same as the preallocated buffer");
52   std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
53 }
54 
55 //===----------------------------------------------------------------------===//
56 // OMPAllocateDecl Implementation.
57 //===----------------------------------------------------------------------===//
58 
59 void OMPAllocateDecl::anchor() { }
60 
61 OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC,
62                                          SourceLocation L, ArrayRef<Expr *> VL,
63                                          ArrayRef<OMPClause *> CL) {
64   OMPAllocateDecl *D = new (
65       C, DC, additionalSizeToAlloc<Expr *, OMPClause *>(VL.size(), CL.size()))
66       OMPAllocateDecl(OMPAllocate, DC, L);
67   D->NumVars = VL.size();
68   D->setVars(VL);
69   D->NumClauses = CL.size();
70   D->setClauses(CL);
71   return D;
72 }
73 
74 OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, unsigned ID,
75                                                      unsigned NVars,
76                                                      unsigned NClauses) {
77   OMPAllocateDecl *D =
78       new (C, ID, additionalSizeToAlloc<Expr *, OMPClause *>(NVars, NClauses))
79           OMPAllocateDecl(OMPAllocate, nullptr, SourceLocation());
80   D->NumVars = NVars;
81   D->NumClauses = NClauses;
82   return D;
83 }
84 
85 void OMPAllocateDecl::setVars(ArrayRef<Expr *> VL) {
86   assert(VL.size() == NumVars &&
87          "Number of variables is not the same as the preallocated buffer");
88   std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
89 }
90 
91 void OMPAllocateDecl::setClauses(ArrayRef<OMPClause *> CL) {
92   assert(CL.size() == NumClauses &&
93          "Number of variables is not the same as the preallocated buffer");
94   std::uninitialized_copy(CL.begin(), CL.end(),
95                           getTrailingObjects<OMPClause *>());
96 }
97 
98 //===----------------------------------------------------------------------===//
99 // OMPRequiresDecl Implementation.
100 //===----------------------------------------------------------------------===//
101 
102 void OMPRequiresDecl::anchor() {}
103 
104 OMPRequiresDecl *OMPRequiresDecl::Create(ASTContext &C, DeclContext *DC,
105                                          SourceLocation L,
106                                          ArrayRef<OMPClause *> CL) {
107   OMPRequiresDecl *D =
108       new (C, DC, additionalSizeToAlloc<OMPClause *>(CL.size()))
109       OMPRequiresDecl(OMPRequires, DC, L);
110   D->NumClauses = CL.size();
111   D->setClauses(CL);
112   return D;
113 }
114 
115 OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, unsigned ID,
116                                                      unsigned N) {
117   OMPRequiresDecl *D = new (C, ID, additionalSizeToAlloc<OMPClause *>(N))
118       OMPRequiresDecl(OMPRequires, nullptr, SourceLocation());
119   D->NumClauses = N;
120   return D;
121 }
122 
123 void OMPRequiresDecl::setClauses(ArrayRef<OMPClause *> CL) {
124   assert(CL.size() == NumClauses &&
125          "Number of clauses is not the same as the preallocated buffer");
126   std::uninitialized_copy(CL.begin(), CL.end(),
127                           getTrailingObjects<OMPClause *>());
128 }
129 
130 //===----------------------------------------------------------------------===//
131 // OMPDeclareReductionDecl Implementation.
132 //===----------------------------------------------------------------------===//
133 
134 OMPDeclareReductionDecl::OMPDeclareReductionDecl(
135     Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
136     QualType Ty, OMPDeclareReductionDecl *PrevDeclInScope)
137     : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
138       PrevDeclInScope(PrevDeclInScope) {
139   setInitializer(nullptr, CallInit);
140 }
141 
142 void OMPDeclareReductionDecl::anchor() {}
143 
144 OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create(
145     ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
146     QualType T, OMPDeclareReductionDecl *PrevDeclInScope) {
147   return new (C, DC) OMPDeclareReductionDecl(OMPDeclareReduction, DC, L, Name,
148                                              T, PrevDeclInScope);
149 }
150 
151 OMPDeclareReductionDecl *
152 OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
153   return new (C, ID) OMPDeclareReductionDecl(
154       OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(), DeclarationName(),
155       QualType(), /*PrevDeclInScope=*/nullptr);
156 }
157 
158 OMPDeclareReductionDecl *OMPDeclareReductionDecl::getPrevDeclInScope() {
159   return cast_or_null<OMPDeclareReductionDecl>(
160       PrevDeclInScope.get(getASTContext().getExternalSource()));
161 }
162 const OMPDeclareReductionDecl *
163 OMPDeclareReductionDecl::getPrevDeclInScope() const {
164   return cast_or_null<OMPDeclareReductionDecl>(
165       PrevDeclInScope.get(getASTContext().getExternalSource()));
166 }
167 
168 //===----------------------------------------------------------------------===//
169 // OMPDeclareMapperDecl Implementation.
170 //===----------------------------------------------------------------------===//
171 
172 void OMPDeclareMapperDecl::anchor() {}
173 
174 OMPDeclareMapperDecl *
175 OMPDeclareMapperDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
176                              DeclarationName Name, QualType T,
177                              DeclarationName VarName,
178                              OMPDeclareMapperDecl *PrevDeclInScope) {
179   return new (C, DC) OMPDeclareMapperDecl(OMPDeclareMapper, DC, L, Name, T,
180                                           VarName, PrevDeclInScope);
181 }
182 
183 OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C,
184                                                                unsigned ID,
185                                                                unsigned N) {
186   auto *D = new (C, ID)
187       OMPDeclareMapperDecl(OMPDeclareMapper, /*DC=*/nullptr, SourceLocation(),
188                            DeclarationName(), QualType(), DeclarationName(),
189                            /*PrevDeclInScope=*/nullptr);
190   if (N) {
191     auto **ClauseStorage = C.Allocate<OMPClause *>(N);
192     D->Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, N);
193   }
194   return D;
195 }
196 
197 /// Creates an array of clauses to this mapper declaration and intializes
198 /// them. The space used to store clause pointers is dynamically allocated,
199 /// because we do not know the number of clauses when creating
200 /// OMPDeclareMapperDecl
201 void OMPDeclareMapperDecl::CreateClauses(ASTContext &C,
202                                          ArrayRef<OMPClause *> CL) {
203   assert(Clauses.empty() && "Number of clauses should be 0 on initialization");
204   size_t NumClauses = CL.size();
205   if (NumClauses) {
206     auto **ClauseStorage = C.Allocate<OMPClause *>(NumClauses);
207     Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
208     setClauses(CL);
209   }
210 }
211 
212 void OMPDeclareMapperDecl::setClauses(ArrayRef<OMPClause *> CL) {
213   assert(CL.size() == Clauses.size() &&
214          "Number of clauses is not the same as the preallocated buffer");
215   std::uninitialized_copy(CL.begin(), CL.end(), Clauses.data());
216 }
217 
218 OMPDeclareMapperDecl *OMPDeclareMapperDecl::getPrevDeclInScope() {
219   return cast_or_null<OMPDeclareMapperDecl>(
220       PrevDeclInScope.get(getASTContext().getExternalSource()));
221 }
222 
223 const OMPDeclareMapperDecl *OMPDeclareMapperDecl::getPrevDeclInScope() const {
224   return cast_or_null<OMPDeclareMapperDecl>(
225       PrevDeclInScope.get(getASTContext().getExternalSource()));
226 }
227 
228 //===----------------------------------------------------------------------===//
229 // OMPCapturedExprDecl Implementation.
230 //===----------------------------------------------------------------------===//
231 
232 void OMPCapturedExprDecl::anchor() {}
233 
234 OMPCapturedExprDecl *OMPCapturedExprDecl::Create(ASTContext &C, DeclContext *DC,
235                                                  IdentifierInfo *Id, QualType T,
236                                                  SourceLocation StartLoc) {
237   return new (C, DC) OMPCapturedExprDecl(
238       C, DC, Id, T, C.getTrivialTypeSourceInfo(T), StartLoc);
239 }
240 
241 OMPCapturedExprDecl *OMPCapturedExprDecl::CreateDeserialized(ASTContext &C,
242                                                              unsigned ID) {
243   return new (C, ID) OMPCapturedExprDecl(C, nullptr, nullptr, QualType(),
244                                          /*TInfo=*/nullptr, SourceLocation());
245 }
246 
247 SourceRange OMPCapturedExprDecl::getSourceRange() const {
248   assert(hasInit());
249   return SourceRange(getInit()->getBeginLoc(), getInit()->getEndLoc());
250 }
251