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