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,
63                                          ArrayRef<Expr *> VL) {
64   OMPAllocateDecl *D = new (C, DC, additionalSizeToAlloc<Expr *>(VL.size()))
65       OMPAllocateDecl(OMPAllocate, DC, L);
66   D->NumVars = VL.size();
67   D->setVars(VL);
68   return D;
69 }
70 
71 OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, unsigned ID,
72                                                      unsigned N) {
73   OMPAllocateDecl *D = new (C, ID, additionalSizeToAlloc<Expr *>(N))
74       OMPAllocateDecl(OMPAllocate, nullptr, SourceLocation());
75   D->NumVars = N;
76   return D;
77 }
78 
79 void OMPAllocateDecl::setVars(ArrayRef<Expr *> VL) {
80   assert(VL.size() == NumVars &&
81          "Number of variables is not the same as the preallocated buffer");
82   std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
83 }
84 
85 //===----------------------------------------------------------------------===//
86 // OMPRequiresDecl Implementation.
87 //===----------------------------------------------------------------------===//
88 
89 void OMPRequiresDecl::anchor() {}
90 
91 OMPRequiresDecl *OMPRequiresDecl::Create(ASTContext &C, DeclContext *DC,
92                                          SourceLocation L,
93                                          ArrayRef<OMPClause *> CL) {
94   OMPRequiresDecl *D =
95       new (C, DC, additionalSizeToAlloc<OMPClause *>(CL.size()))
96       OMPRequiresDecl(OMPRequires, DC, L);
97   D->NumClauses = CL.size();
98   D->setClauses(CL);
99   return D;
100 }
101 
102 OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, unsigned ID,
103                                                      unsigned N) {
104   OMPRequiresDecl *D = new (C, ID, additionalSizeToAlloc<OMPClause *>(N))
105       OMPRequiresDecl(OMPRequires, nullptr, SourceLocation());
106   D->NumClauses = N;
107   return D;
108 }
109 
110 void OMPRequiresDecl::setClauses(ArrayRef<OMPClause *> CL) {
111   assert(CL.size() == NumClauses &&
112          "Number of clauses is not the same as the preallocated buffer");
113   std::uninitialized_copy(CL.begin(), CL.end(),
114                           getTrailingObjects<OMPClause *>());
115 }
116 
117 //===----------------------------------------------------------------------===//
118 // OMPDeclareReductionDecl Implementation.
119 //===----------------------------------------------------------------------===//
120 
121 OMPDeclareReductionDecl::OMPDeclareReductionDecl(
122     Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
123     QualType Ty, OMPDeclareReductionDecl *PrevDeclInScope)
124     : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
125       PrevDeclInScope(PrevDeclInScope) {
126   setInitializer(nullptr, CallInit);
127 }
128 
129 void OMPDeclareReductionDecl::anchor() {}
130 
131 OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create(
132     ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
133     QualType T, OMPDeclareReductionDecl *PrevDeclInScope) {
134   return new (C, DC) OMPDeclareReductionDecl(OMPDeclareReduction, DC, L, Name,
135                                              T, PrevDeclInScope);
136 }
137 
138 OMPDeclareReductionDecl *
139 OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
140   return new (C, ID) OMPDeclareReductionDecl(
141       OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(), DeclarationName(),
142       QualType(), /*PrevDeclInScope=*/nullptr);
143 }
144 
145 OMPDeclareReductionDecl *OMPDeclareReductionDecl::getPrevDeclInScope() {
146   return cast_or_null<OMPDeclareReductionDecl>(
147       PrevDeclInScope.get(getASTContext().getExternalSource()));
148 }
149 const OMPDeclareReductionDecl *
150 OMPDeclareReductionDecl::getPrevDeclInScope() const {
151   return cast_or_null<OMPDeclareReductionDecl>(
152       PrevDeclInScope.get(getASTContext().getExternalSource()));
153 }
154 
155 //===----------------------------------------------------------------------===//
156 // OMPDeclareMapperDecl Implementation.
157 //===----------------------------------------------------------------------===//
158 
159 void OMPDeclareMapperDecl::anchor() {}
160 
161 OMPDeclareMapperDecl *
162 OMPDeclareMapperDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
163                              DeclarationName Name, QualType T,
164                              DeclarationName VarName,
165                              OMPDeclareMapperDecl *PrevDeclInScope) {
166   return new (C, DC) OMPDeclareMapperDecl(OMPDeclareMapper, DC, L, Name, T,
167                                           VarName, PrevDeclInScope);
168 }
169 
170 OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C,
171                                                                unsigned ID,
172                                                                unsigned N) {
173   auto *D = new (C, ID)
174       OMPDeclareMapperDecl(OMPDeclareMapper, /*DC=*/nullptr, SourceLocation(),
175                            DeclarationName(), QualType(), DeclarationName(),
176                            /*PrevDeclInScope=*/nullptr);
177   if (N) {
178     auto **ClauseStorage = C.Allocate<OMPClause *>(N);
179     D->Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, N);
180   }
181   return D;
182 }
183 
184 /// Creates an array of clauses to this mapper declaration and intializes
185 /// them. The space used to store clause pointers is dynamically allocated,
186 /// because we do not know the number of clauses when creating
187 /// OMPDeclareMapperDecl
188 void OMPDeclareMapperDecl::CreateClauses(ASTContext &C,
189                                          ArrayRef<OMPClause *> CL) {
190   assert(Clauses.empty() && "Number of clauses should be 0 on initialization");
191   size_t NumClauses = CL.size();
192   if (NumClauses) {
193     auto **ClauseStorage = C.Allocate<OMPClause *>(NumClauses);
194     Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
195     setClauses(CL);
196   }
197 }
198 
199 void OMPDeclareMapperDecl::setClauses(ArrayRef<OMPClause *> CL) {
200   assert(CL.size() == Clauses.size() &&
201          "Number of clauses is not the same as the preallocated buffer");
202   std::uninitialized_copy(CL.begin(), CL.end(), Clauses.data());
203 }
204 
205 OMPDeclareMapperDecl *OMPDeclareMapperDecl::getPrevDeclInScope() {
206   return cast_or_null<OMPDeclareMapperDecl>(
207       PrevDeclInScope.get(getASTContext().getExternalSource()));
208 }
209 
210 const OMPDeclareMapperDecl *OMPDeclareMapperDecl::getPrevDeclInScope() const {
211   return cast_or_null<OMPDeclareMapperDecl>(
212       PrevDeclInScope.get(getASTContext().getExternalSource()));
213 }
214 
215 //===----------------------------------------------------------------------===//
216 // OMPCapturedExprDecl Implementation.
217 //===----------------------------------------------------------------------===//
218 
219 void OMPCapturedExprDecl::anchor() {}
220 
221 OMPCapturedExprDecl *OMPCapturedExprDecl::Create(ASTContext &C, DeclContext *DC,
222                                                  IdentifierInfo *Id, QualType T,
223                                                  SourceLocation StartLoc) {
224   return new (C, DC) OMPCapturedExprDecl(
225       C, DC, Id, T, C.getTrivialTypeSourceInfo(T), StartLoc);
226 }
227 
228 OMPCapturedExprDecl *OMPCapturedExprDecl::CreateDeserialized(ASTContext &C,
229                                                              unsigned ID) {
230   return new (C, ID) OMPCapturedExprDecl(C, nullptr, nullptr, QualType(),
231                                          /*TInfo=*/nullptr, SourceLocation());
232 }
233 
234 SourceRange OMPCapturedExprDecl::getSourceRange() const {
235   assert(hasInit());
236   return SourceRange(getInit()->getBeginLoc(), getInit()->getEndLoc());
237 }
238