xref: /minix3/external/bsd/llvm/dist/clang/lib/Sema/SemaOpenMP.cpp (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ----------===//
2*f4a2713aSLionel Sambuc //
3*f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4*f4a2713aSLionel Sambuc //
5*f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7*f4a2713aSLionel Sambuc //
8*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9*f4a2713aSLionel Sambuc /// \file
10*f4a2713aSLionel Sambuc /// \brief This file implements semantic analysis for OpenMP directives and
11*f4a2713aSLionel Sambuc /// clauses.
12*f4a2713aSLionel Sambuc ///
13*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14*f4a2713aSLionel Sambuc 
15*f4a2713aSLionel Sambuc #include "clang/Basic/OpenMPKinds.h"
16*f4a2713aSLionel Sambuc #include "clang/AST/Decl.h"
17*f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
18*f4a2713aSLionel Sambuc #include "clang/AST/DeclOpenMP.h"
19*f4a2713aSLionel Sambuc #include "clang/AST/StmtCXX.h"
20*f4a2713aSLionel Sambuc #include "clang/AST/StmtOpenMP.h"
21*f4a2713aSLionel Sambuc #include "clang/AST/StmtVisitor.h"
22*f4a2713aSLionel Sambuc #include "clang/Lex/Preprocessor.h"
23*f4a2713aSLionel Sambuc #include "clang/Sema/Initialization.h"
24*f4a2713aSLionel Sambuc #include "clang/Sema/SemaInternal.h"
25*f4a2713aSLionel Sambuc #include "clang/Sema/Lookup.h"
26*f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h"
27*f4a2713aSLionel Sambuc #include "clang/Sema/ScopeInfo.h"
28*f4a2713aSLionel Sambuc using namespace clang;
29*f4a2713aSLionel Sambuc 
30*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
31*f4a2713aSLionel Sambuc // Stack of data-sharing attributes for variables
32*f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
33*f4a2713aSLionel Sambuc 
34*f4a2713aSLionel Sambuc namespace {
35*f4a2713aSLionel Sambuc /// \brief Default data sharing attributes, which can be applied to directive.
36*f4a2713aSLionel Sambuc enum DefaultDataSharingAttributes {
37*f4a2713aSLionel Sambuc   DSA_unspecified = 0,   /// \brief Data sharing attribute not specified.
38*f4a2713aSLionel Sambuc   DSA_none = 1 << 0,     /// \brief Default data sharing attribute 'none'.
39*f4a2713aSLionel Sambuc   DSA_shared = 1 << 1    /// \brief Default data sharing attribute 'shared'.
40*f4a2713aSLionel Sambuc };
41*f4a2713aSLionel Sambuc 
42*f4a2713aSLionel Sambuc /// \brief Stack for tracking declarations used in OpenMP directives and
43*f4a2713aSLionel Sambuc /// clauses and their data-sharing attributes.
44*f4a2713aSLionel Sambuc class DSAStackTy {
45*f4a2713aSLionel Sambuc public:
46*f4a2713aSLionel Sambuc   struct DSAVarData {
47*f4a2713aSLionel Sambuc     OpenMPDirectiveKind DKind;
48*f4a2713aSLionel Sambuc     OpenMPClauseKind CKind;
49*f4a2713aSLionel Sambuc     DeclRefExpr *RefExpr;
50*f4a2713aSLionel Sambuc     DSAVarData() : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(0) { }
51*f4a2713aSLionel Sambuc   };
52*f4a2713aSLionel Sambuc private:
53*f4a2713aSLionel Sambuc   struct DSAInfo {
54*f4a2713aSLionel Sambuc     OpenMPClauseKind Attributes;
55*f4a2713aSLionel Sambuc     DeclRefExpr *RefExpr;
56*f4a2713aSLionel Sambuc   };
57*f4a2713aSLionel Sambuc   typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
58*f4a2713aSLionel Sambuc 
59*f4a2713aSLionel Sambuc   struct SharingMapTy {
60*f4a2713aSLionel Sambuc     DeclSAMapTy SharingMap;
61*f4a2713aSLionel Sambuc     DefaultDataSharingAttributes DefaultAttr;
62*f4a2713aSLionel Sambuc     OpenMPDirectiveKind Directive;
63*f4a2713aSLionel Sambuc     DeclarationNameInfo DirectiveName;
64*f4a2713aSLionel Sambuc     Scope *CurScope;
65*f4a2713aSLionel Sambuc     SharingMapTy(OpenMPDirectiveKind DKind,
66*f4a2713aSLionel Sambuc                  const DeclarationNameInfo &Name,
67*f4a2713aSLionel Sambuc                  Scope *CurScope)
68*f4a2713aSLionel Sambuc       : SharingMap(), DefaultAttr(DSA_unspecified), Directive(DKind),
69*f4a2713aSLionel Sambuc         DirectiveName(Name), CurScope(CurScope) { }
70*f4a2713aSLionel Sambuc     SharingMapTy()
71*f4a2713aSLionel Sambuc       : SharingMap(), DefaultAttr(DSA_unspecified),
72*f4a2713aSLionel Sambuc         Directive(OMPD_unknown), DirectiveName(),
73*f4a2713aSLionel Sambuc         CurScope(0) { }
74*f4a2713aSLionel Sambuc   };
75*f4a2713aSLionel Sambuc 
76*f4a2713aSLionel Sambuc   typedef SmallVector<SharingMapTy, 64> StackTy;
77*f4a2713aSLionel Sambuc 
78*f4a2713aSLionel Sambuc   /// \brief Stack of used declaration and their data-sharing attributes.
79*f4a2713aSLionel Sambuc   StackTy Stack;
80*f4a2713aSLionel Sambuc   Sema &Actions;
81*f4a2713aSLionel Sambuc 
82*f4a2713aSLionel Sambuc   typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
83*f4a2713aSLionel Sambuc 
84*f4a2713aSLionel Sambuc   DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D);
85*f4a2713aSLionel Sambuc public:
86*f4a2713aSLionel Sambuc   explicit DSAStackTy(Sema &S) : Stack(1), Actions(S) { }
87*f4a2713aSLionel Sambuc 
88*f4a2713aSLionel Sambuc   void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
89*f4a2713aSLionel Sambuc             Scope *CurScope) {
90*f4a2713aSLionel Sambuc     Stack.push_back(SharingMapTy(DKind, DirName, CurScope));
91*f4a2713aSLionel Sambuc   }
92*f4a2713aSLionel Sambuc 
93*f4a2713aSLionel Sambuc   void pop() {
94*f4a2713aSLionel Sambuc     assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!");
95*f4a2713aSLionel Sambuc     Stack.pop_back();
96*f4a2713aSLionel Sambuc   }
97*f4a2713aSLionel Sambuc 
98*f4a2713aSLionel Sambuc   /// \brief Adds explicit data sharing attribute to the specified declaration.
99*f4a2713aSLionel Sambuc   void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
100*f4a2713aSLionel Sambuc 
101*f4a2713aSLionel Sambuc   /// \brief Checks if the variable is a local for OpenMP region.
102*f4a2713aSLionel Sambuc   bool isOpenMPLocal(VarDecl *D);
103*f4a2713aSLionel Sambuc 
104*f4a2713aSLionel Sambuc   /// \brief Returns data sharing attributes from top of the stack for the
105*f4a2713aSLionel Sambuc   /// specified declaration.
106*f4a2713aSLionel Sambuc   DSAVarData getTopDSA(VarDecl *D);
107*f4a2713aSLionel Sambuc   /// \brief Returns data-sharing attributes for the specified declaration.
108*f4a2713aSLionel Sambuc   DSAVarData getImplicitDSA(VarDecl *D);
109*f4a2713aSLionel Sambuc   /// \brief Checks if the specified variables has \a CKind data-sharing
110*f4a2713aSLionel Sambuc   /// attribute in \a DKind directive.
111*f4a2713aSLionel Sambuc   DSAVarData hasDSA(VarDecl *D, OpenMPClauseKind CKind,
112*f4a2713aSLionel Sambuc                     OpenMPDirectiveKind DKind = OMPD_unknown);
113*f4a2713aSLionel Sambuc 
114*f4a2713aSLionel Sambuc 
115*f4a2713aSLionel Sambuc   /// \brief Returns currently analyzed directive.
116*f4a2713aSLionel Sambuc   OpenMPDirectiveKind getCurrentDirective() const {
117*f4a2713aSLionel Sambuc     return Stack.back().Directive;
118*f4a2713aSLionel Sambuc   }
119*f4a2713aSLionel Sambuc 
120*f4a2713aSLionel Sambuc   /// \brief Set default data sharing attribute to none.
121*f4a2713aSLionel Sambuc   void setDefaultDSANone() { Stack.back().DefaultAttr = DSA_none; }
122*f4a2713aSLionel Sambuc   /// \brief Set default data sharing attribute to shared.
123*f4a2713aSLionel Sambuc   void setDefaultDSAShared() { Stack.back().DefaultAttr = DSA_shared; }
124*f4a2713aSLionel Sambuc 
125*f4a2713aSLionel Sambuc   DefaultDataSharingAttributes getDefaultDSA() const {
126*f4a2713aSLionel Sambuc     return Stack.back().DefaultAttr;
127*f4a2713aSLionel Sambuc   }
128*f4a2713aSLionel Sambuc 
129*f4a2713aSLionel Sambuc   Scope *getCurScope() { return Stack.back().CurScope; }
130*f4a2713aSLionel Sambuc };
131*f4a2713aSLionel Sambuc } // end anonymous namespace.
132*f4a2713aSLionel Sambuc 
133*f4a2713aSLionel Sambuc DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
134*f4a2713aSLionel Sambuc                                           VarDecl *D) {
135*f4a2713aSLionel Sambuc   DSAVarData DVar;
136*f4a2713aSLionel Sambuc   if (Iter == Stack.rend() - 1) {
137*f4a2713aSLionel Sambuc     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
138*f4a2713aSLionel Sambuc     // in a region but not in construct]
139*f4a2713aSLionel Sambuc     //  File-scope or namespace-scope variables referenced in called routines
140*f4a2713aSLionel Sambuc     //  in the region are shared unless they appear in a threadprivate
141*f4a2713aSLionel Sambuc     //  directive.
142*f4a2713aSLionel Sambuc     // TODO
143*f4a2713aSLionel Sambuc     if (!D->isFunctionOrMethodVarDecl())
144*f4a2713aSLionel Sambuc       DVar.CKind = OMPC_shared;
145*f4a2713aSLionel Sambuc 
146*f4a2713aSLionel Sambuc     // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
147*f4a2713aSLionel Sambuc     // in a region but not in construct]
148*f4a2713aSLionel Sambuc     //  Variables with static storage duration that are declared in called
149*f4a2713aSLionel Sambuc     //  routines in the region are shared.
150*f4a2713aSLionel Sambuc     if (D->hasGlobalStorage())
151*f4a2713aSLionel Sambuc       DVar.CKind = OMPC_shared;
152*f4a2713aSLionel Sambuc 
153*f4a2713aSLionel Sambuc     return DVar;
154*f4a2713aSLionel Sambuc   }
155*f4a2713aSLionel Sambuc   DVar.DKind = Iter->Directive;
156*f4a2713aSLionel Sambuc   // Explicitly specified attributes and local variables with predetermined
157*f4a2713aSLionel Sambuc   // attributes.
158*f4a2713aSLionel Sambuc   if (Iter->SharingMap.count(D)) {
159*f4a2713aSLionel Sambuc     DVar.RefExpr = Iter->SharingMap[D].RefExpr;
160*f4a2713aSLionel Sambuc     DVar.CKind = Iter->SharingMap[D].Attributes;
161*f4a2713aSLionel Sambuc     return DVar;
162*f4a2713aSLionel Sambuc   }
163*f4a2713aSLionel Sambuc 
164*f4a2713aSLionel Sambuc   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
165*f4a2713aSLionel Sambuc   // in a Construct, C/C++, implicitly determined, p.1]
166*f4a2713aSLionel Sambuc   //  In a parallel or task construct, the data-sharing attributes of these
167*f4a2713aSLionel Sambuc   //  variables are determined by the default clause, if present.
168*f4a2713aSLionel Sambuc   switch (Iter->DefaultAttr) {
169*f4a2713aSLionel Sambuc   case DSA_shared:
170*f4a2713aSLionel Sambuc     DVar.CKind = OMPC_shared;
171*f4a2713aSLionel Sambuc     return DVar;
172*f4a2713aSLionel Sambuc   case DSA_none:
173*f4a2713aSLionel Sambuc     return DVar;
174*f4a2713aSLionel Sambuc   case DSA_unspecified:
175*f4a2713aSLionel Sambuc     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
176*f4a2713aSLionel Sambuc     // in a Construct, implicitly determined, p.2]
177*f4a2713aSLionel Sambuc     //  In a parallel construct, if no default clause is present, these
178*f4a2713aSLionel Sambuc     //  variables are shared.
179*f4a2713aSLionel Sambuc     if (DVar.DKind == OMPD_parallel) {
180*f4a2713aSLionel Sambuc       DVar.CKind = OMPC_shared;
181*f4a2713aSLionel Sambuc       return DVar;
182*f4a2713aSLionel Sambuc     }
183*f4a2713aSLionel Sambuc 
184*f4a2713aSLionel Sambuc     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
185*f4a2713aSLionel Sambuc     // in a Construct, implicitly determined, p.4]
186*f4a2713aSLionel Sambuc     //  In a task construct, if no default clause is present, a variable that in
187*f4a2713aSLionel Sambuc     //  the enclosing context is determined to be shared by all implicit tasks
188*f4a2713aSLionel Sambuc     //  bound to the current team is shared.
189*f4a2713aSLionel Sambuc     // TODO
190*f4a2713aSLionel Sambuc     if (DVar.DKind == OMPD_task) {
191*f4a2713aSLionel Sambuc       DSAVarData DVarTemp;
192*f4a2713aSLionel Sambuc       for (StackTy::reverse_iterator I = Iter + 1,
193*f4a2713aSLionel Sambuc                                      EE = Stack.rend() - 1;
194*f4a2713aSLionel Sambuc            I != EE; ++I) {
195*f4a2713aSLionel Sambuc         // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
196*f4a2713aSLionel Sambuc         // in a Construct, implicitly determined, p.6]
197*f4a2713aSLionel Sambuc         //  In a task construct, if no default clause is present, a variable
198*f4a2713aSLionel Sambuc         //  whose data-sharing attribute is not determined by the rules above is
199*f4a2713aSLionel Sambuc         //  firstprivate.
200*f4a2713aSLionel Sambuc         DVarTemp = getDSA(I, D);
201*f4a2713aSLionel Sambuc         if (DVarTemp.CKind != OMPC_shared) {
202*f4a2713aSLionel Sambuc           DVar.RefExpr = 0;
203*f4a2713aSLionel Sambuc           DVar.DKind = OMPD_task;
204*f4a2713aSLionel Sambuc           DVar.CKind = OMPC_firstprivate;
205*f4a2713aSLionel Sambuc           return DVar;
206*f4a2713aSLionel Sambuc         }
207*f4a2713aSLionel Sambuc         if (I->Directive == OMPD_parallel) break;
208*f4a2713aSLionel Sambuc       }
209*f4a2713aSLionel Sambuc       DVar.DKind = OMPD_task;
210*f4a2713aSLionel Sambuc       DVar.CKind =
211*f4a2713aSLionel Sambuc         (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
212*f4a2713aSLionel Sambuc       return DVar;
213*f4a2713aSLionel Sambuc     }
214*f4a2713aSLionel Sambuc   }
215*f4a2713aSLionel Sambuc   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
216*f4a2713aSLionel Sambuc   // in a Construct, implicitly determined, p.3]
217*f4a2713aSLionel Sambuc   //  For constructs other than task, if no default clause is present, these
218*f4a2713aSLionel Sambuc   //  variables inherit their data-sharing attributes from the enclosing
219*f4a2713aSLionel Sambuc   //  context.
220*f4a2713aSLionel Sambuc   return getDSA(Iter + 1, D);
221*f4a2713aSLionel Sambuc }
222*f4a2713aSLionel Sambuc 
223*f4a2713aSLionel Sambuc void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
224*f4a2713aSLionel Sambuc   if (A == OMPC_threadprivate) {
225*f4a2713aSLionel Sambuc     Stack[0].SharingMap[D].Attributes = A;
226*f4a2713aSLionel Sambuc     Stack[0].SharingMap[D].RefExpr = E;
227*f4a2713aSLionel Sambuc   } else {
228*f4a2713aSLionel Sambuc     assert(Stack.size() > 1 && "Data-sharing attributes stack is empty");
229*f4a2713aSLionel Sambuc     Stack.back().SharingMap[D].Attributes = A;
230*f4a2713aSLionel Sambuc     Stack.back().SharingMap[D].RefExpr = E;
231*f4a2713aSLionel Sambuc   }
232*f4a2713aSLionel Sambuc }
233*f4a2713aSLionel Sambuc 
234*f4a2713aSLionel Sambuc bool DSAStackTy::isOpenMPLocal(VarDecl *D) {
235*f4a2713aSLionel Sambuc   Scope *CurScope = getCurScope();
236*f4a2713aSLionel Sambuc   while (CurScope && !CurScope->isDeclScope(D))
237*f4a2713aSLionel Sambuc     CurScope = CurScope->getParent();
238*f4a2713aSLionel Sambuc   while (CurScope && !CurScope->isOpenMPDirectiveScope())
239*f4a2713aSLionel Sambuc     CurScope = CurScope->getParent();
240*f4a2713aSLionel Sambuc   bool isOpenMPLocal = !!CurScope;
241*f4a2713aSLionel Sambuc   if (!isOpenMPLocal) {
242*f4a2713aSLionel Sambuc     CurScope = getCurScope();
243*f4a2713aSLionel Sambuc     while (CurScope && !CurScope->isOpenMPDirectiveScope())
244*f4a2713aSLionel Sambuc       CurScope = CurScope->getParent();
245*f4a2713aSLionel Sambuc     isOpenMPLocal =
246*f4a2713aSLionel Sambuc       CurScope &&
247*f4a2713aSLionel Sambuc       isa<CapturedDecl>(D->getDeclContext()) &&
248*f4a2713aSLionel Sambuc       CurScope->getFnParent()->getEntity()->Encloses(D->getDeclContext());
249*f4a2713aSLionel Sambuc   }
250*f4a2713aSLionel Sambuc   return isOpenMPLocal;
251*f4a2713aSLionel Sambuc }
252*f4a2713aSLionel Sambuc 
253*f4a2713aSLionel Sambuc DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D) {
254*f4a2713aSLionel Sambuc   DSAVarData DVar;
255*f4a2713aSLionel Sambuc 
256*f4a2713aSLionel Sambuc   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
257*f4a2713aSLionel Sambuc   // in a Construct, C/C++, predetermined, p.1]
258*f4a2713aSLionel Sambuc   //  Variables appearing in threadprivate directives are threadprivate.
259*f4a2713aSLionel Sambuc   if (D->getTLSKind() != VarDecl::TLS_None) {
260*f4a2713aSLionel Sambuc     DVar.CKind = OMPC_threadprivate;
261*f4a2713aSLionel Sambuc     return DVar;
262*f4a2713aSLionel Sambuc   }
263*f4a2713aSLionel Sambuc   if (Stack[0].SharingMap.count(D)) {
264*f4a2713aSLionel Sambuc     DVar.RefExpr = Stack[0].SharingMap[D].RefExpr;
265*f4a2713aSLionel Sambuc     DVar.CKind = OMPC_threadprivate;
266*f4a2713aSLionel Sambuc     return DVar;
267*f4a2713aSLionel Sambuc   }
268*f4a2713aSLionel Sambuc 
269*f4a2713aSLionel Sambuc   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
270*f4a2713aSLionel Sambuc   // in a Construct, C/C++, predetermined, p.1]
271*f4a2713aSLionel Sambuc   // Variables with automatic storage duration that are declared in a scope
272*f4a2713aSLionel Sambuc   // inside the construct are private.
273*f4a2713aSLionel Sambuc   if (isOpenMPLocal(D) && D->isLocalVarDecl() &&
274*f4a2713aSLionel Sambuc       (D->getStorageClass() == SC_Auto ||
275*f4a2713aSLionel Sambuc        D->getStorageClass() == SC_None)) {
276*f4a2713aSLionel Sambuc     DVar.CKind = OMPC_private;
277*f4a2713aSLionel Sambuc     return DVar;
278*f4a2713aSLionel Sambuc   }
279*f4a2713aSLionel Sambuc 
280*f4a2713aSLionel Sambuc   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
281*f4a2713aSLionel Sambuc   // in a Construct, C/C++, predetermined, p.4]
282*f4a2713aSLionel Sambuc   //  Static data memebers are shared.
283*f4a2713aSLionel Sambuc   if (D->isStaticDataMember()) {
284*f4a2713aSLionel Sambuc     // Variables with const-qualified type having no mutable member may be listed
285*f4a2713aSLionel Sambuc     // in a firstprivate clause, even if they are static data members.
286*f4a2713aSLionel Sambuc     DSAVarData DVarTemp = hasDSA(D, OMPC_firstprivate);
287*f4a2713aSLionel Sambuc     if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
288*f4a2713aSLionel Sambuc       return DVar;
289*f4a2713aSLionel Sambuc 
290*f4a2713aSLionel Sambuc     DVar.CKind = OMPC_shared;
291*f4a2713aSLionel Sambuc     return DVar;
292*f4a2713aSLionel Sambuc   }
293*f4a2713aSLionel Sambuc 
294*f4a2713aSLionel Sambuc   QualType Type = D->getType().getNonReferenceType().getCanonicalType();
295*f4a2713aSLionel Sambuc   bool IsConstant = Type.isConstant(Actions.getASTContext());
296*f4a2713aSLionel Sambuc   while (Type->isArrayType()) {
297*f4a2713aSLionel Sambuc     QualType ElemType = cast<ArrayType>(Type.getTypePtr())->getElementType();
298*f4a2713aSLionel Sambuc     Type = ElemType.getNonReferenceType().getCanonicalType();
299*f4a2713aSLionel Sambuc   }
300*f4a2713aSLionel Sambuc   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
301*f4a2713aSLionel Sambuc   // in a Construct, C/C++, predetermined, p.6]
302*f4a2713aSLionel Sambuc   //  Variables with const qualified type having no mutable member are
303*f4a2713aSLionel Sambuc   //  shared.
304*f4a2713aSLionel Sambuc   CXXRecordDecl *RD = Actions.getLangOpts().CPlusPlus ?
305*f4a2713aSLionel Sambuc                                 Type->getAsCXXRecordDecl() : 0;
306*f4a2713aSLionel Sambuc   if (IsConstant &&
307*f4a2713aSLionel Sambuc       !(Actions.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) {
308*f4a2713aSLionel Sambuc     // Variables with const-qualified type having no mutable member may be
309*f4a2713aSLionel Sambuc     // listed in a firstprivate clause, even if they are static data members.
310*f4a2713aSLionel Sambuc     DSAVarData DVarTemp = hasDSA(D, OMPC_firstprivate);
311*f4a2713aSLionel Sambuc     if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
312*f4a2713aSLionel Sambuc       return DVar;
313*f4a2713aSLionel Sambuc 
314*f4a2713aSLionel Sambuc     DVar.CKind = OMPC_shared;
315*f4a2713aSLionel Sambuc     return DVar;
316*f4a2713aSLionel Sambuc   }
317*f4a2713aSLionel Sambuc 
318*f4a2713aSLionel Sambuc   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
319*f4a2713aSLionel Sambuc   // in a Construct, C/C++, predetermined, p.7]
320*f4a2713aSLionel Sambuc   //  Variables with static storage duration that are declared in a scope
321*f4a2713aSLionel Sambuc   //  inside the construct are shared.
322*f4a2713aSLionel Sambuc   if (isOpenMPLocal(D) && D->isStaticLocal()) {
323*f4a2713aSLionel Sambuc     DVar.CKind = OMPC_shared;
324*f4a2713aSLionel Sambuc     return DVar;
325*f4a2713aSLionel Sambuc   }
326*f4a2713aSLionel Sambuc 
327*f4a2713aSLionel Sambuc   // Explicitly specified attributes and local variables with predetermined
328*f4a2713aSLionel Sambuc   // attributes.
329*f4a2713aSLionel Sambuc   if (Stack.back().SharingMap.count(D)) {
330*f4a2713aSLionel Sambuc     DVar.RefExpr = Stack.back().SharingMap[D].RefExpr;
331*f4a2713aSLionel Sambuc     DVar.CKind = Stack.back().SharingMap[D].Attributes;
332*f4a2713aSLionel Sambuc   }
333*f4a2713aSLionel Sambuc 
334*f4a2713aSLionel Sambuc   return DVar;
335*f4a2713aSLionel Sambuc }
336*f4a2713aSLionel Sambuc 
337*f4a2713aSLionel Sambuc DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D) {
338*f4a2713aSLionel Sambuc   return getDSA(Stack.rbegin() + 1, D);
339*f4a2713aSLionel Sambuc }
340*f4a2713aSLionel Sambuc 
341*f4a2713aSLionel Sambuc DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, OpenMPClauseKind CKind,
342*f4a2713aSLionel Sambuc                                           OpenMPDirectiveKind DKind) {
343*f4a2713aSLionel Sambuc   for (StackTy::reverse_iterator I = Stack.rbegin() + 1,
344*f4a2713aSLionel Sambuc                                  E = Stack.rend() - 1;
345*f4a2713aSLionel Sambuc        I != E; ++I) {
346*f4a2713aSLionel Sambuc     if (DKind != OMPD_unknown && DKind != I->Directive) continue;
347*f4a2713aSLionel Sambuc     DSAVarData DVar = getDSA(I, D);
348*f4a2713aSLionel Sambuc     if (DVar.CKind == CKind)
349*f4a2713aSLionel Sambuc       return DVar;
350*f4a2713aSLionel Sambuc   }
351*f4a2713aSLionel Sambuc   return DSAVarData();
352*f4a2713aSLionel Sambuc }
353*f4a2713aSLionel Sambuc 
354*f4a2713aSLionel Sambuc void Sema::InitDataSharingAttributesStack() {
355*f4a2713aSLionel Sambuc   VarDataSharingAttributesStack = new DSAStackTy(*this);
356*f4a2713aSLionel Sambuc }
357*f4a2713aSLionel Sambuc 
358*f4a2713aSLionel Sambuc #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
359*f4a2713aSLionel Sambuc 
360*f4a2713aSLionel Sambuc void Sema::DestroyDataSharingAttributesStack() {
361*f4a2713aSLionel Sambuc   delete DSAStack;
362*f4a2713aSLionel Sambuc }
363*f4a2713aSLionel Sambuc 
364*f4a2713aSLionel Sambuc void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
365*f4a2713aSLionel Sambuc                                const DeclarationNameInfo &DirName,
366*f4a2713aSLionel Sambuc                                Scope *CurScope) {
367*f4a2713aSLionel Sambuc   DSAStack->push(DKind, DirName, CurScope);
368*f4a2713aSLionel Sambuc   PushExpressionEvaluationContext(PotentiallyEvaluated);
369*f4a2713aSLionel Sambuc }
370*f4a2713aSLionel Sambuc 
371*f4a2713aSLionel Sambuc void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
372*f4a2713aSLionel Sambuc   DSAStack->pop();
373*f4a2713aSLionel Sambuc   DiscardCleanupsInEvaluationContext();
374*f4a2713aSLionel Sambuc   PopExpressionEvaluationContext();
375*f4a2713aSLionel Sambuc }
376*f4a2713aSLionel Sambuc 
377*f4a2713aSLionel Sambuc namespace {
378*f4a2713aSLionel Sambuc 
379*f4a2713aSLionel Sambuc class VarDeclFilterCCC : public CorrectionCandidateCallback {
380*f4a2713aSLionel Sambuc private:
381*f4a2713aSLionel Sambuc   Sema &Actions;
382*f4a2713aSLionel Sambuc public:
383*f4a2713aSLionel Sambuc   VarDeclFilterCCC(Sema &S) : Actions(S) { }
384*f4a2713aSLionel Sambuc   virtual bool ValidateCandidate(const TypoCorrection &Candidate) {
385*f4a2713aSLionel Sambuc     NamedDecl *ND = Candidate.getCorrectionDecl();
386*f4a2713aSLionel Sambuc     if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
387*f4a2713aSLionel Sambuc       return VD->hasGlobalStorage() &&
388*f4a2713aSLionel Sambuc              Actions.isDeclInScope(ND, Actions.getCurLexicalContext(),
389*f4a2713aSLionel Sambuc                                    Actions.getCurScope());
390*f4a2713aSLionel Sambuc     }
391*f4a2713aSLionel Sambuc     return false;
392*f4a2713aSLionel Sambuc   }
393*f4a2713aSLionel Sambuc };
394*f4a2713aSLionel Sambuc }
395*f4a2713aSLionel Sambuc 
396*f4a2713aSLionel Sambuc ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
397*f4a2713aSLionel Sambuc                                          CXXScopeSpec &ScopeSpec,
398*f4a2713aSLionel Sambuc                                          const DeclarationNameInfo &Id) {
399*f4a2713aSLionel Sambuc   LookupResult Lookup(*this, Id, LookupOrdinaryName);
400*f4a2713aSLionel Sambuc   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
401*f4a2713aSLionel Sambuc 
402*f4a2713aSLionel Sambuc   if (Lookup.isAmbiguous())
403*f4a2713aSLionel Sambuc     return ExprError();
404*f4a2713aSLionel Sambuc 
405*f4a2713aSLionel Sambuc   VarDecl *VD;
406*f4a2713aSLionel Sambuc   if (!Lookup.isSingleResult()) {
407*f4a2713aSLionel Sambuc     VarDeclFilterCCC Validator(*this);
408*f4a2713aSLionel Sambuc     if (TypoCorrection Corrected = CorrectTypo(Id, LookupOrdinaryName, CurScope,
409*f4a2713aSLionel Sambuc                                                0, Validator)) {
410*f4a2713aSLionel Sambuc       diagnoseTypo(Corrected,
411*f4a2713aSLionel Sambuc                    PDiag(Lookup.empty()? diag::err_undeclared_var_use_suggest
412*f4a2713aSLionel Sambuc                                        : diag::err_omp_expected_var_arg_suggest)
413*f4a2713aSLionel Sambuc                      << Id.getName());
414*f4a2713aSLionel Sambuc       VD = Corrected.getCorrectionDeclAs<VarDecl>();
415*f4a2713aSLionel Sambuc     } else {
416*f4a2713aSLionel Sambuc       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
417*f4a2713aSLionel Sambuc                                        : diag::err_omp_expected_var_arg)
418*f4a2713aSLionel Sambuc           << Id.getName();
419*f4a2713aSLionel Sambuc       return ExprError();
420*f4a2713aSLionel Sambuc     }
421*f4a2713aSLionel Sambuc   } else {
422*f4a2713aSLionel Sambuc     if (!(VD = Lookup.getAsSingle<VarDecl>())) {
423*f4a2713aSLionel Sambuc       Diag(Id.getLoc(), diag::err_omp_expected_var_arg)
424*f4a2713aSLionel Sambuc         << Id.getName();
425*f4a2713aSLionel Sambuc       Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
426*f4a2713aSLionel Sambuc       return ExprError();
427*f4a2713aSLionel Sambuc     }
428*f4a2713aSLionel Sambuc   }
429*f4a2713aSLionel Sambuc   Lookup.suppressDiagnostics();
430*f4a2713aSLionel Sambuc 
431*f4a2713aSLionel Sambuc   // OpenMP [2.9.2, Syntax, C/C++]
432*f4a2713aSLionel Sambuc   //   Variables must be file-scope, namespace-scope, or static block-scope.
433*f4a2713aSLionel Sambuc   if (!VD->hasGlobalStorage()) {
434*f4a2713aSLionel Sambuc     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
435*f4a2713aSLionel Sambuc       << getOpenMPDirectiveName(OMPD_threadprivate)
436*f4a2713aSLionel Sambuc       << !VD->isStaticLocal();
437*f4a2713aSLionel Sambuc     bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
438*f4a2713aSLionel Sambuc                   VarDecl::DeclarationOnly;
439*f4a2713aSLionel Sambuc     Diag(VD->getLocation(),
440*f4a2713aSLionel Sambuc          IsDecl ? diag::note_previous_decl : diag::note_defined_here) << VD;
441*f4a2713aSLionel Sambuc     return ExprError();
442*f4a2713aSLionel Sambuc   }
443*f4a2713aSLionel Sambuc 
444*f4a2713aSLionel Sambuc   VarDecl *CanonicalVD = VD->getCanonicalDecl();
445*f4a2713aSLionel Sambuc   NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
446*f4a2713aSLionel Sambuc   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
447*f4a2713aSLionel Sambuc   //   A threadprivate directive for file-scope variables must appear outside
448*f4a2713aSLionel Sambuc   //   any definition or declaration.
449*f4a2713aSLionel Sambuc   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
450*f4a2713aSLionel Sambuc       !getCurLexicalContext()->isTranslationUnit()) {
451*f4a2713aSLionel Sambuc     Diag(Id.getLoc(), diag::err_omp_var_scope)
452*f4a2713aSLionel Sambuc       << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
453*f4a2713aSLionel Sambuc     bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
454*f4a2713aSLionel Sambuc                   VarDecl::DeclarationOnly;
455*f4a2713aSLionel Sambuc     Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
456*f4a2713aSLionel Sambuc                                      diag::note_defined_here) << VD;
457*f4a2713aSLionel Sambuc     return ExprError();
458*f4a2713aSLionel Sambuc   }
459*f4a2713aSLionel Sambuc   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
460*f4a2713aSLionel Sambuc   //   A threadprivate directive for static class member variables must appear
461*f4a2713aSLionel Sambuc   //   in the class definition, in the same scope in which the member
462*f4a2713aSLionel Sambuc   //   variables are declared.
463*f4a2713aSLionel Sambuc   if (CanonicalVD->isStaticDataMember() &&
464*f4a2713aSLionel Sambuc       !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
465*f4a2713aSLionel Sambuc     Diag(Id.getLoc(), diag::err_omp_var_scope)
466*f4a2713aSLionel Sambuc       << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
467*f4a2713aSLionel Sambuc     bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
468*f4a2713aSLionel Sambuc                   VarDecl::DeclarationOnly;
469*f4a2713aSLionel Sambuc     Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
470*f4a2713aSLionel Sambuc                                      diag::note_defined_here) << VD;
471*f4a2713aSLionel Sambuc     return ExprError();
472*f4a2713aSLionel Sambuc   }
473*f4a2713aSLionel Sambuc   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
474*f4a2713aSLionel Sambuc   //   A threadprivate directive for namespace-scope variables must appear
475*f4a2713aSLionel Sambuc   //   outside any definition or declaration other than the namespace
476*f4a2713aSLionel Sambuc   //   definition itself.
477*f4a2713aSLionel Sambuc   if (CanonicalVD->getDeclContext()->isNamespace() &&
478*f4a2713aSLionel Sambuc       (!getCurLexicalContext()->isFileContext() ||
479*f4a2713aSLionel Sambuc        !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
480*f4a2713aSLionel Sambuc     Diag(Id.getLoc(), diag::err_omp_var_scope)
481*f4a2713aSLionel Sambuc       << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
482*f4a2713aSLionel Sambuc     bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
483*f4a2713aSLionel Sambuc                   VarDecl::DeclarationOnly;
484*f4a2713aSLionel Sambuc     Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
485*f4a2713aSLionel Sambuc                                      diag::note_defined_here) << VD;
486*f4a2713aSLionel Sambuc     return ExprError();
487*f4a2713aSLionel Sambuc   }
488*f4a2713aSLionel Sambuc   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
489*f4a2713aSLionel Sambuc   //   A threadprivate directive for static block-scope variables must appear
490*f4a2713aSLionel Sambuc   //   in the scope of the variable and not in a nested scope.
491*f4a2713aSLionel Sambuc   if (CanonicalVD->isStaticLocal() && CurScope &&
492*f4a2713aSLionel Sambuc       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
493*f4a2713aSLionel Sambuc     Diag(Id.getLoc(), diag::err_omp_var_scope)
494*f4a2713aSLionel Sambuc       << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
495*f4a2713aSLionel Sambuc     bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
496*f4a2713aSLionel Sambuc                   VarDecl::DeclarationOnly;
497*f4a2713aSLionel Sambuc     Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
498*f4a2713aSLionel Sambuc                                      diag::note_defined_here) << VD;
499*f4a2713aSLionel Sambuc     return ExprError();
500*f4a2713aSLionel Sambuc   }
501*f4a2713aSLionel Sambuc 
502*f4a2713aSLionel Sambuc   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
503*f4a2713aSLionel Sambuc   //   A threadprivate directive must lexically precede all references to any
504*f4a2713aSLionel Sambuc   //   of the variables in its list.
505*f4a2713aSLionel Sambuc   if (VD->isUsed()) {
506*f4a2713aSLionel Sambuc     Diag(Id.getLoc(), diag::err_omp_var_used)
507*f4a2713aSLionel Sambuc       << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
508*f4a2713aSLionel Sambuc     return ExprError();
509*f4a2713aSLionel Sambuc   }
510*f4a2713aSLionel Sambuc 
511*f4a2713aSLionel Sambuc   QualType ExprType = VD->getType().getNonReferenceType();
512*f4a2713aSLionel Sambuc   ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_RValue, Id.getLoc());
513*f4a2713aSLionel Sambuc   DSAStack->addDSA(VD, cast<DeclRefExpr>(DE.get()), OMPC_threadprivate);
514*f4a2713aSLionel Sambuc   return DE;
515*f4a2713aSLionel Sambuc }
516*f4a2713aSLionel Sambuc 
517*f4a2713aSLionel Sambuc Sema::DeclGroupPtrTy Sema::ActOnOpenMPThreadprivateDirective(
518*f4a2713aSLionel Sambuc                                 SourceLocation Loc,
519*f4a2713aSLionel Sambuc                                 ArrayRef<Expr *> VarList) {
520*f4a2713aSLionel Sambuc   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
521*f4a2713aSLionel Sambuc     CurContext->addDecl(D);
522*f4a2713aSLionel Sambuc     return DeclGroupPtrTy::make(DeclGroupRef(D));
523*f4a2713aSLionel Sambuc   }
524*f4a2713aSLionel Sambuc   return DeclGroupPtrTy();
525*f4a2713aSLionel Sambuc }
526*f4a2713aSLionel Sambuc 
527*f4a2713aSLionel Sambuc OMPThreadPrivateDecl *Sema::CheckOMPThreadPrivateDecl(
528*f4a2713aSLionel Sambuc                                  SourceLocation Loc,
529*f4a2713aSLionel Sambuc                                  ArrayRef<Expr *> VarList) {
530*f4a2713aSLionel Sambuc   SmallVector<Expr *, 8> Vars;
531*f4a2713aSLionel Sambuc   for (ArrayRef<Expr *>::iterator I = VarList.begin(),
532*f4a2713aSLionel Sambuc                                          E = VarList.end();
533*f4a2713aSLionel Sambuc        I != E; ++I) {
534*f4a2713aSLionel Sambuc     DeclRefExpr *DE = cast<DeclRefExpr>(*I);
535*f4a2713aSLionel Sambuc     VarDecl *VD = cast<VarDecl>(DE->getDecl());
536*f4a2713aSLionel Sambuc     SourceLocation ILoc = DE->getExprLoc();
537*f4a2713aSLionel Sambuc 
538*f4a2713aSLionel Sambuc     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
539*f4a2713aSLionel Sambuc     //   A threadprivate variable must not have an incomplete type.
540*f4a2713aSLionel Sambuc     if (RequireCompleteType(ILoc, VD->getType(),
541*f4a2713aSLionel Sambuc                             diag::err_omp_threadprivate_incomplete_type)) {
542*f4a2713aSLionel Sambuc       continue;
543*f4a2713aSLionel Sambuc     }
544*f4a2713aSLionel Sambuc 
545*f4a2713aSLionel Sambuc     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
546*f4a2713aSLionel Sambuc     //   A threadprivate variable must not have a reference type.
547*f4a2713aSLionel Sambuc     if (VD->getType()->isReferenceType()) {
548*f4a2713aSLionel Sambuc       Diag(ILoc, diag::err_omp_ref_type_arg)
549*f4a2713aSLionel Sambuc         << getOpenMPDirectiveName(OMPD_threadprivate)
550*f4a2713aSLionel Sambuc         << VD->getType();
551*f4a2713aSLionel Sambuc       bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
552*f4a2713aSLionel Sambuc                     VarDecl::DeclarationOnly;
553*f4a2713aSLionel Sambuc       Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
554*f4a2713aSLionel Sambuc                                        diag::note_defined_here) << VD;
555*f4a2713aSLionel Sambuc       continue;
556*f4a2713aSLionel Sambuc     }
557*f4a2713aSLionel Sambuc 
558*f4a2713aSLionel Sambuc     // Check if this is a TLS variable.
559*f4a2713aSLionel Sambuc     if (VD->getTLSKind()) {
560*f4a2713aSLionel Sambuc       Diag(ILoc, diag::err_omp_var_thread_local) << VD;
561*f4a2713aSLionel Sambuc       bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
562*f4a2713aSLionel Sambuc                     VarDecl::DeclarationOnly;
563*f4a2713aSLionel Sambuc       Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
564*f4a2713aSLionel Sambuc                                        diag::note_defined_here) << VD;
565*f4a2713aSLionel Sambuc       continue;
566*f4a2713aSLionel Sambuc     }
567*f4a2713aSLionel Sambuc 
568*f4a2713aSLionel Sambuc     Vars.push_back(*I);
569*f4a2713aSLionel Sambuc   }
570*f4a2713aSLionel Sambuc   return Vars.empty() ?
571*f4a2713aSLionel Sambuc               0 : OMPThreadPrivateDecl::Create(Context,
572*f4a2713aSLionel Sambuc                                                getCurLexicalContext(),
573*f4a2713aSLionel Sambuc                                                Loc, Vars);
574*f4a2713aSLionel Sambuc }
575*f4a2713aSLionel Sambuc 
576*f4a2713aSLionel Sambuc namespace {
577*f4a2713aSLionel Sambuc class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
578*f4a2713aSLionel Sambuc   DSAStackTy *Stack;
579*f4a2713aSLionel Sambuc   Sema &Actions;
580*f4a2713aSLionel Sambuc   bool ErrorFound;
581*f4a2713aSLionel Sambuc   CapturedStmt *CS;
582*f4a2713aSLionel Sambuc   llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
583*f4a2713aSLionel Sambuc public:
584*f4a2713aSLionel Sambuc   void VisitDeclRefExpr(DeclRefExpr *E) {
585*f4a2713aSLionel Sambuc     if(VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
586*f4a2713aSLionel Sambuc       // Skip internally declared variables.
587*f4a2713aSLionel Sambuc       if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) return;
588*f4a2713aSLionel Sambuc 
589*f4a2713aSLionel Sambuc       SourceLocation ELoc = E->getExprLoc();
590*f4a2713aSLionel Sambuc 
591*f4a2713aSLionel Sambuc       OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
592*f4a2713aSLionel Sambuc       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD);
593*f4a2713aSLionel Sambuc       if (DVar.CKind != OMPC_unknown) {
594*f4a2713aSLionel Sambuc         if (DKind == OMPD_task && DVar.CKind != OMPC_shared &&
595*f4a2713aSLionel Sambuc             DVar.CKind != OMPC_threadprivate && !DVar.RefExpr)
596*f4a2713aSLionel Sambuc           ImplicitFirstprivate.push_back(DVar.RefExpr);
597*f4a2713aSLionel Sambuc         return;
598*f4a2713aSLionel Sambuc       }
599*f4a2713aSLionel Sambuc       // The default(none) clause requires that each variable that is referenced
600*f4a2713aSLionel Sambuc       // in the construct, and does not have a predetermined data-sharing
601*f4a2713aSLionel Sambuc       // attribute, must have its data-sharing attribute explicitly determined
602*f4a2713aSLionel Sambuc       // by being listed in a data-sharing attribute clause.
603*f4a2713aSLionel Sambuc       if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
604*f4a2713aSLionel Sambuc           (DKind == OMPD_parallel || DKind == OMPD_task)) {
605*f4a2713aSLionel Sambuc         ErrorFound = true;
606*f4a2713aSLionel Sambuc         Actions.Diag(ELoc, diag::err_omp_no_dsa_for_variable) << VD;
607*f4a2713aSLionel Sambuc         return;
608*f4a2713aSLionel Sambuc       }
609*f4a2713aSLionel Sambuc 
610*f4a2713aSLionel Sambuc       // OpenMP [2.9.3.6, Restrictions, p.2]
611*f4a2713aSLionel Sambuc       //  A list item that appears in a reduction clause of the innermost
612*f4a2713aSLionel Sambuc       //  enclosing worksharing or parallel construct may not be accessed in an
613*f4a2713aSLionel Sambuc       //  explicit task.
614*f4a2713aSLionel Sambuc       // TODO:
615*f4a2713aSLionel Sambuc 
616*f4a2713aSLionel Sambuc       // Define implicit data-sharing attributes for task.
617*f4a2713aSLionel Sambuc       DVar = Stack->getImplicitDSA(VD);
618*f4a2713aSLionel Sambuc       if (DKind == OMPD_task && DVar.CKind != OMPC_shared)
619*f4a2713aSLionel Sambuc         ImplicitFirstprivate.push_back(DVar.RefExpr);
620*f4a2713aSLionel Sambuc     }
621*f4a2713aSLionel Sambuc   }
622*f4a2713aSLionel Sambuc   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
623*f4a2713aSLionel Sambuc     for (ArrayRef<OMPClause *>::iterator I = S->clauses().begin(),
624*f4a2713aSLionel Sambuc                                          E = S->clauses().end();
625*f4a2713aSLionel Sambuc          I != E; ++I)
626*f4a2713aSLionel Sambuc       if (OMPClause *C = *I)
627*f4a2713aSLionel Sambuc         for (StmtRange R = C->children(); R; ++R)
628*f4a2713aSLionel Sambuc           if (Stmt *Child = *R)
629*f4a2713aSLionel Sambuc             Visit(Child);
630*f4a2713aSLionel Sambuc   }
631*f4a2713aSLionel Sambuc   void VisitStmt(Stmt *S) {
632*f4a2713aSLionel Sambuc     for (Stmt::child_iterator I = S->child_begin(), E = S->child_end();
633*f4a2713aSLionel Sambuc          I != E; ++I)
634*f4a2713aSLionel Sambuc       if (Stmt *Child = *I)
635*f4a2713aSLionel Sambuc         if (!isa<OMPExecutableDirective>(Child))
636*f4a2713aSLionel Sambuc           Visit(Child);
637*f4a2713aSLionel Sambuc     }
638*f4a2713aSLionel Sambuc 
639*f4a2713aSLionel Sambuc   bool isErrorFound() { return ErrorFound; }
640*f4a2713aSLionel Sambuc   ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; }
641*f4a2713aSLionel Sambuc 
642*f4a2713aSLionel Sambuc   DSAAttrChecker(DSAStackTy *S, Sema &Actions, CapturedStmt *CS)
643*f4a2713aSLionel Sambuc     : Stack(S), Actions(Actions), ErrorFound(false), CS(CS) { }
644*f4a2713aSLionel Sambuc };
645*f4a2713aSLionel Sambuc }
646*f4a2713aSLionel Sambuc 
647*f4a2713aSLionel Sambuc StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
648*f4a2713aSLionel Sambuc                                                 ArrayRef<OMPClause *> Clauses,
649*f4a2713aSLionel Sambuc                                                 Stmt *AStmt,
650*f4a2713aSLionel Sambuc                                                 SourceLocation StartLoc,
651*f4a2713aSLionel Sambuc                                                 SourceLocation EndLoc) {
652*f4a2713aSLionel Sambuc   assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
653*f4a2713aSLionel Sambuc 
654*f4a2713aSLionel Sambuc   StmtResult Res = StmtError();
655*f4a2713aSLionel Sambuc 
656*f4a2713aSLionel Sambuc   // Check default data sharing attributes for referenced variables.
657*f4a2713aSLionel Sambuc   DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
658*f4a2713aSLionel Sambuc   DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt());
659*f4a2713aSLionel Sambuc   if (DSAChecker.isErrorFound())
660*f4a2713aSLionel Sambuc     return StmtError();
661*f4a2713aSLionel Sambuc   // Generate list of implicitly defined firstprivate variables.
662*f4a2713aSLionel Sambuc   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
663*f4a2713aSLionel Sambuc   ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
664*f4a2713aSLionel Sambuc 
665*f4a2713aSLionel Sambuc   bool ErrorFound = false;
666*f4a2713aSLionel Sambuc   if (!DSAChecker.getImplicitFirstprivate().empty()) {
667*f4a2713aSLionel Sambuc     if (OMPClause *Implicit =
668*f4a2713aSLionel Sambuc          ActOnOpenMPFirstprivateClause(DSAChecker.getImplicitFirstprivate(),
669*f4a2713aSLionel Sambuc                                        SourceLocation(), SourceLocation(),
670*f4a2713aSLionel Sambuc                                        SourceLocation())) {
671*f4a2713aSLionel Sambuc       ClausesWithImplicit.push_back(Implicit);
672*f4a2713aSLionel Sambuc       ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
673*f4a2713aSLionel Sambuc                                     DSAChecker.getImplicitFirstprivate().size();
674*f4a2713aSLionel Sambuc     } else
675*f4a2713aSLionel Sambuc       ErrorFound = true;
676*f4a2713aSLionel Sambuc   }
677*f4a2713aSLionel Sambuc 
678*f4a2713aSLionel Sambuc   switch (Kind) {
679*f4a2713aSLionel Sambuc   case OMPD_parallel:
680*f4a2713aSLionel Sambuc     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt,
681*f4a2713aSLionel Sambuc                                        StartLoc, EndLoc);
682*f4a2713aSLionel Sambuc     break;
683*f4a2713aSLionel Sambuc   case OMPD_threadprivate:
684*f4a2713aSLionel Sambuc   case OMPD_task:
685*f4a2713aSLionel Sambuc     llvm_unreachable("OpenMP Directive is not allowed");
686*f4a2713aSLionel Sambuc   case OMPD_unknown:
687*f4a2713aSLionel Sambuc   case NUM_OPENMP_DIRECTIVES:
688*f4a2713aSLionel Sambuc     llvm_unreachable("Unknown OpenMP directive");
689*f4a2713aSLionel Sambuc   }
690*f4a2713aSLionel Sambuc 
691*f4a2713aSLionel Sambuc   if (ErrorFound) return StmtError();
692*f4a2713aSLionel Sambuc   return Res;
693*f4a2713aSLionel Sambuc }
694*f4a2713aSLionel Sambuc 
695*f4a2713aSLionel Sambuc StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
696*f4a2713aSLionel Sambuc                                               Stmt *AStmt,
697*f4a2713aSLionel Sambuc                                               SourceLocation StartLoc,
698*f4a2713aSLionel Sambuc                                               SourceLocation EndLoc) {
699*f4a2713aSLionel Sambuc   getCurFunction()->setHasBranchProtectedScope();
700*f4a2713aSLionel Sambuc 
701*f4a2713aSLionel Sambuc   return Owned(OMPParallelDirective::Create(Context, StartLoc, EndLoc,
702*f4a2713aSLionel Sambuc                                             Clauses, AStmt));
703*f4a2713aSLionel Sambuc }
704*f4a2713aSLionel Sambuc 
705*f4a2713aSLionel Sambuc OMPClause *Sema::ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,
706*f4a2713aSLionel Sambuc                                          unsigned Argument,
707*f4a2713aSLionel Sambuc                                          SourceLocation ArgumentLoc,
708*f4a2713aSLionel Sambuc                                          SourceLocation StartLoc,
709*f4a2713aSLionel Sambuc                                          SourceLocation LParenLoc,
710*f4a2713aSLionel Sambuc                                          SourceLocation EndLoc) {
711*f4a2713aSLionel Sambuc   OMPClause *Res = 0;
712*f4a2713aSLionel Sambuc   switch (Kind) {
713*f4a2713aSLionel Sambuc   case OMPC_default:
714*f4a2713aSLionel Sambuc     Res =
715*f4a2713aSLionel Sambuc       ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
716*f4a2713aSLionel Sambuc                                ArgumentLoc, StartLoc, LParenLoc, EndLoc);
717*f4a2713aSLionel Sambuc     break;
718*f4a2713aSLionel Sambuc   case OMPC_private:
719*f4a2713aSLionel Sambuc   case OMPC_firstprivate:
720*f4a2713aSLionel Sambuc   case OMPC_shared:
721*f4a2713aSLionel Sambuc   case OMPC_threadprivate:
722*f4a2713aSLionel Sambuc   case OMPC_unknown:
723*f4a2713aSLionel Sambuc   case NUM_OPENMP_CLAUSES:
724*f4a2713aSLionel Sambuc     llvm_unreachable("Clause is not allowed.");
725*f4a2713aSLionel Sambuc   }
726*f4a2713aSLionel Sambuc   return Res;
727*f4a2713aSLionel Sambuc }
728*f4a2713aSLionel Sambuc 
729*f4a2713aSLionel Sambuc OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind,
730*f4a2713aSLionel Sambuc                                           SourceLocation KindKwLoc,
731*f4a2713aSLionel Sambuc                                           SourceLocation StartLoc,
732*f4a2713aSLionel Sambuc                                           SourceLocation LParenLoc,
733*f4a2713aSLionel Sambuc                                           SourceLocation EndLoc) {
734*f4a2713aSLionel Sambuc   if (Kind == OMPC_DEFAULT_unknown) {
735*f4a2713aSLionel Sambuc     std::string Values;
736*f4a2713aSLionel Sambuc     std::string Sep(NUM_OPENMP_DEFAULT_KINDS > 1 ? ", " : "");
737*f4a2713aSLionel Sambuc     for (unsigned i = OMPC_DEFAULT_unknown + 1;
738*f4a2713aSLionel Sambuc          i < NUM_OPENMP_DEFAULT_KINDS; ++i) {
739*f4a2713aSLionel Sambuc       Values += "'";
740*f4a2713aSLionel Sambuc       Values += getOpenMPSimpleClauseTypeName(OMPC_default, i);
741*f4a2713aSLionel Sambuc       Values += "'";
742*f4a2713aSLionel Sambuc       switch (i) {
743*f4a2713aSLionel Sambuc       case NUM_OPENMP_DEFAULT_KINDS - 2:
744*f4a2713aSLionel Sambuc         Values += " or ";
745*f4a2713aSLionel Sambuc         break;
746*f4a2713aSLionel Sambuc       case NUM_OPENMP_DEFAULT_KINDS - 1:
747*f4a2713aSLionel Sambuc         break;
748*f4a2713aSLionel Sambuc       default:
749*f4a2713aSLionel Sambuc         Values += Sep;
750*f4a2713aSLionel Sambuc         break;
751*f4a2713aSLionel Sambuc       }
752*f4a2713aSLionel Sambuc     }
753*f4a2713aSLionel Sambuc     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
754*f4a2713aSLionel Sambuc       << Values << getOpenMPClauseName(OMPC_default);
755*f4a2713aSLionel Sambuc     return 0;
756*f4a2713aSLionel Sambuc   }
757*f4a2713aSLionel Sambuc   switch (Kind) {
758*f4a2713aSLionel Sambuc   case OMPC_DEFAULT_none:
759*f4a2713aSLionel Sambuc     DSAStack->setDefaultDSANone();
760*f4a2713aSLionel Sambuc     break;
761*f4a2713aSLionel Sambuc   case OMPC_DEFAULT_shared:
762*f4a2713aSLionel Sambuc     DSAStack->setDefaultDSAShared();
763*f4a2713aSLionel Sambuc     break;
764*f4a2713aSLionel Sambuc   default:
765*f4a2713aSLionel Sambuc     break;
766*f4a2713aSLionel Sambuc   }
767*f4a2713aSLionel Sambuc   return new (Context) OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc,
768*f4a2713aSLionel Sambuc                                         EndLoc);
769*f4a2713aSLionel Sambuc }
770*f4a2713aSLionel Sambuc 
771*f4a2713aSLionel Sambuc OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
772*f4a2713aSLionel Sambuc                                           ArrayRef<Expr *> VarList,
773*f4a2713aSLionel Sambuc                                           SourceLocation StartLoc,
774*f4a2713aSLionel Sambuc                                           SourceLocation LParenLoc,
775*f4a2713aSLionel Sambuc                                           SourceLocation EndLoc) {
776*f4a2713aSLionel Sambuc   OMPClause *Res = 0;
777*f4a2713aSLionel Sambuc   switch (Kind) {
778*f4a2713aSLionel Sambuc   case OMPC_private:
779*f4a2713aSLionel Sambuc     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
780*f4a2713aSLionel Sambuc     break;
781*f4a2713aSLionel Sambuc   case OMPC_firstprivate:
782*f4a2713aSLionel Sambuc     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
783*f4a2713aSLionel Sambuc     break;
784*f4a2713aSLionel Sambuc   case OMPC_shared:
785*f4a2713aSLionel Sambuc     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
786*f4a2713aSLionel Sambuc     break;
787*f4a2713aSLionel Sambuc   case OMPC_default:
788*f4a2713aSLionel Sambuc   case OMPC_threadprivate:
789*f4a2713aSLionel Sambuc   case OMPC_unknown:
790*f4a2713aSLionel Sambuc   case NUM_OPENMP_CLAUSES:
791*f4a2713aSLionel Sambuc     llvm_unreachable("Clause is not allowed.");
792*f4a2713aSLionel Sambuc   }
793*f4a2713aSLionel Sambuc   return Res;
794*f4a2713aSLionel Sambuc }
795*f4a2713aSLionel Sambuc 
796*f4a2713aSLionel Sambuc OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
797*f4a2713aSLionel Sambuc                                           SourceLocation StartLoc,
798*f4a2713aSLionel Sambuc                                           SourceLocation LParenLoc,
799*f4a2713aSLionel Sambuc                                           SourceLocation EndLoc) {
800*f4a2713aSLionel Sambuc   SmallVector<Expr *, 8> Vars;
801*f4a2713aSLionel Sambuc   for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
802*f4a2713aSLionel Sambuc        I != E; ++I) {
803*f4a2713aSLionel Sambuc     assert(*I && "NULL expr in OpenMP private clause.");
804*f4a2713aSLionel Sambuc     if (isa<DependentScopeDeclRefExpr>(*I)) {
805*f4a2713aSLionel Sambuc       // It will be analyzed later.
806*f4a2713aSLionel Sambuc       Vars.push_back(*I);
807*f4a2713aSLionel Sambuc       continue;
808*f4a2713aSLionel Sambuc     }
809*f4a2713aSLionel Sambuc 
810*f4a2713aSLionel Sambuc     SourceLocation ELoc = (*I)->getExprLoc();
811*f4a2713aSLionel Sambuc     // OpenMP [2.1, C/C++]
812*f4a2713aSLionel Sambuc     //  A list item is a variable name.
813*f4a2713aSLionel Sambuc     // OpenMP  [2.9.3.3, Restrictions, p.1]
814*f4a2713aSLionel Sambuc     //  A variable that is part of another variable (as an array or
815*f4a2713aSLionel Sambuc     //  structure element) cannot appear in a private clause.
816*f4a2713aSLionel Sambuc     DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(*I);
817*f4a2713aSLionel Sambuc     if (!DE || !isa<VarDecl>(DE->getDecl())) {
818*f4a2713aSLionel Sambuc       Diag(ELoc, diag::err_omp_expected_var_name)
819*f4a2713aSLionel Sambuc         << (*I)->getSourceRange();
820*f4a2713aSLionel Sambuc       continue;
821*f4a2713aSLionel Sambuc     }
822*f4a2713aSLionel Sambuc     Decl *D = DE->getDecl();
823*f4a2713aSLionel Sambuc     VarDecl *VD = cast<VarDecl>(D);
824*f4a2713aSLionel Sambuc 
825*f4a2713aSLionel Sambuc     QualType Type = VD->getType();
826*f4a2713aSLionel Sambuc     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
827*f4a2713aSLionel Sambuc       // It will be analyzed later.
828*f4a2713aSLionel Sambuc       Vars.push_back(DE);
829*f4a2713aSLionel Sambuc       continue;
830*f4a2713aSLionel Sambuc     }
831*f4a2713aSLionel Sambuc 
832*f4a2713aSLionel Sambuc     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
833*f4a2713aSLionel Sambuc     //  A variable that appears in a private clause must not have an incomplete
834*f4a2713aSLionel Sambuc     //  type or a reference type.
835*f4a2713aSLionel Sambuc     if (RequireCompleteType(ELoc, Type,
836*f4a2713aSLionel Sambuc                             diag::err_omp_private_incomplete_type)) {
837*f4a2713aSLionel Sambuc       continue;
838*f4a2713aSLionel Sambuc     }
839*f4a2713aSLionel Sambuc     if (Type->isReferenceType()) {
840*f4a2713aSLionel Sambuc       Diag(ELoc, diag::err_omp_clause_ref_type_arg)
841*f4a2713aSLionel Sambuc         << getOpenMPClauseName(OMPC_private) << Type;
842*f4a2713aSLionel Sambuc       bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
843*f4a2713aSLionel Sambuc                     VarDecl::DeclarationOnly;
844*f4a2713aSLionel Sambuc       Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
845*f4a2713aSLionel Sambuc                                        diag::note_defined_here) << VD;
846*f4a2713aSLionel Sambuc       continue;
847*f4a2713aSLionel Sambuc     }
848*f4a2713aSLionel Sambuc 
849*f4a2713aSLionel Sambuc     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
850*f4a2713aSLionel Sambuc     //  A variable of class type (or array thereof) that appears in a private
851*f4a2713aSLionel Sambuc     //  clause requires an accesible, unambiguous default constructor for the
852*f4a2713aSLionel Sambuc     //  class type.
853*f4a2713aSLionel Sambuc     while (Type.getNonReferenceType()->isArrayType()) {
854*f4a2713aSLionel Sambuc       Type = cast<ArrayType>(
855*f4a2713aSLionel Sambuc                  Type.getNonReferenceType().getTypePtr())->getElementType();
856*f4a2713aSLionel Sambuc     }
857*f4a2713aSLionel Sambuc     CXXRecordDecl *RD = getLangOpts().CPlusPlus ?
858*f4a2713aSLionel Sambuc                           Type.getNonReferenceType()->getAsCXXRecordDecl() : 0;
859*f4a2713aSLionel Sambuc     if (RD) {
860*f4a2713aSLionel Sambuc       CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
861*f4a2713aSLionel Sambuc       PartialDiagnostic PD =
862*f4a2713aSLionel Sambuc         PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
863*f4a2713aSLionel Sambuc       if (!CD ||
864*f4a2713aSLionel Sambuc           CheckConstructorAccess(ELoc, CD,
865*f4a2713aSLionel Sambuc                                  InitializedEntity::InitializeTemporary(Type),
866*f4a2713aSLionel Sambuc                                  CD->getAccess(), PD) == AR_inaccessible ||
867*f4a2713aSLionel Sambuc           CD->isDeleted()) {
868*f4a2713aSLionel Sambuc         Diag(ELoc, diag::err_omp_required_method)
869*f4a2713aSLionel Sambuc              << getOpenMPClauseName(OMPC_private) << 0;
870*f4a2713aSLionel Sambuc         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
871*f4a2713aSLionel Sambuc                       VarDecl::DeclarationOnly;
872*f4a2713aSLionel Sambuc         Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
873*f4a2713aSLionel Sambuc                                          diag::note_defined_here) << VD;
874*f4a2713aSLionel Sambuc         Diag(RD->getLocation(), diag::note_previous_decl) << RD;
875*f4a2713aSLionel Sambuc         continue;
876*f4a2713aSLionel Sambuc       }
877*f4a2713aSLionel Sambuc       MarkFunctionReferenced(ELoc, CD);
878*f4a2713aSLionel Sambuc       DiagnoseUseOfDecl(CD, ELoc);
879*f4a2713aSLionel Sambuc 
880*f4a2713aSLionel Sambuc       CXXDestructorDecl *DD = RD->getDestructor();
881*f4a2713aSLionel Sambuc       if (DD) {
882*f4a2713aSLionel Sambuc         if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
883*f4a2713aSLionel Sambuc             DD->isDeleted()) {
884*f4a2713aSLionel Sambuc           Diag(ELoc, diag::err_omp_required_method)
885*f4a2713aSLionel Sambuc                << getOpenMPClauseName(OMPC_private) << 4;
886*f4a2713aSLionel Sambuc           bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
887*f4a2713aSLionel Sambuc                         VarDecl::DeclarationOnly;
888*f4a2713aSLionel Sambuc           Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
889*f4a2713aSLionel Sambuc                                            diag::note_defined_here) << VD;
890*f4a2713aSLionel Sambuc           Diag(RD->getLocation(), diag::note_previous_decl) << RD;
891*f4a2713aSLionel Sambuc           continue;
892*f4a2713aSLionel Sambuc         }
893*f4a2713aSLionel Sambuc         MarkFunctionReferenced(ELoc, DD);
894*f4a2713aSLionel Sambuc         DiagnoseUseOfDecl(DD, ELoc);
895*f4a2713aSLionel Sambuc       }
896*f4a2713aSLionel Sambuc     }
897*f4a2713aSLionel Sambuc 
898*f4a2713aSLionel Sambuc     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
899*f4a2713aSLionel Sambuc     // in a Construct]
900*f4a2713aSLionel Sambuc     //  Variables with the predetermined data-sharing attributes may not be
901*f4a2713aSLionel Sambuc     //  listed in data-sharing attributes clauses, except for the cases
902*f4a2713aSLionel Sambuc     //  listed below. For these exceptions only, listing a predetermined
903*f4a2713aSLionel Sambuc     //  variable in a data-sharing attribute clause is allowed and overrides
904*f4a2713aSLionel Sambuc     //  the variable's predetermined data-sharing attributes.
905*f4a2713aSLionel Sambuc     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
906*f4a2713aSLionel Sambuc     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
907*f4a2713aSLionel Sambuc       Diag(ELoc, diag::err_omp_wrong_dsa)
908*f4a2713aSLionel Sambuc          << getOpenMPClauseName(DVar.CKind)
909*f4a2713aSLionel Sambuc          << getOpenMPClauseName(OMPC_private);
910*f4a2713aSLionel Sambuc       if (DVar.RefExpr) {
911*f4a2713aSLionel Sambuc         Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
912*f4a2713aSLionel Sambuc              << getOpenMPClauseName(DVar.CKind);
913*f4a2713aSLionel Sambuc       } else {
914*f4a2713aSLionel Sambuc         Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
915*f4a2713aSLionel Sambuc              << getOpenMPClauseName(DVar.CKind);
916*f4a2713aSLionel Sambuc       }
917*f4a2713aSLionel Sambuc       continue;
918*f4a2713aSLionel Sambuc     }
919*f4a2713aSLionel Sambuc 
920*f4a2713aSLionel Sambuc     DSAStack->addDSA(VD, DE, OMPC_private);
921*f4a2713aSLionel Sambuc     Vars.push_back(DE);
922*f4a2713aSLionel Sambuc   }
923*f4a2713aSLionel Sambuc 
924*f4a2713aSLionel Sambuc   if (Vars.empty()) return 0;
925*f4a2713aSLionel Sambuc 
926*f4a2713aSLionel Sambuc   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
927*f4a2713aSLionel Sambuc }
928*f4a2713aSLionel Sambuc 
929*f4a2713aSLionel Sambuc OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
930*f4a2713aSLionel Sambuc                                                SourceLocation StartLoc,
931*f4a2713aSLionel Sambuc                                                SourceLocation LParenLoc,
932*f4a2713aSLionel Sambuc                                                SourceLocation EndLoc) {
933*f4a2713aSLionel Sambuc   SmallVector<Expr *, 8> Vars;
934*f4a2713aSLionel Sambuc   for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
935*f4a2713aSLionel Sambuc        I != E; ++I) {
936*f4a2713aSLionel Sambuc     assert(*I && "NULL expr in OpenMP firstprivate clause.");
937*f4a2713aSLionel Sambuc     if (isa<DependentScopeDeclRefExpr>(*I)) {
938*f4a2713aSLionel Sambuc       // It will be analyzed later.
939*f4a2713aSLionel Sambuc       Vars.push_back(*I);
940*f4a2713aSLionel Sambuc       continue;
941*f4a2713aSLionel Sambuc     }
942*f4a2713aSLionel Sambuc 
943*f4a2713aSLionel Sambuc     SourceLocation ELoc = (*I)->getExprLoc();
944*f4a2713aSLionel Sambuc     // OpenMP [2.1, C/C++]
945*f4a2713aSLionel Sambuc     //  A list item is a variable name.
946*f4a2713aSLionel Sambuc     // OpenMP  [2.9.3.3, Restrictions, p.1]
947*f4a2713aSLionel Sambuc     //  A variable that is part of another variable (as an array or
948*f4a2713aSLionel Sambuc     //  structure element) cannot appear in a private clause.
949*f4a2713aSLionel Sambuc     DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(*I);
950*f4a2713aSLionel Sambuc     if (!DE || !isa<VarDecl>(DE->getDecl())) {
951*f4a2713aSLionel Sambuc       Diag(ELoc, diag::err_omp_expected_var_name)
952*f4a2713aSLionel Sambuc         << (*I)->getSourceRange();
953*f4a2713aSLionel Sambuc       continue;
954*f4a2713aSLionel Sambuc     }
955*f4a2713aSLionel Sambuc     Decl *D = DE->getDecl();
956*f4a2713aSLionel Sambuc     VarDecl *VD = cast<VarDecl>(D);
957*f4a2713aSLionel Sambuc 
958*f4a2713aSLionel Sambuc     QualType Type = VD->getType();
959*f4a2713aSLionel Sambuc     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
960*f4a2713aSLionel Sambuc       // It will be analyzed later.
961*f4a2713aSLionel Sambuc       Vars.push_back(DE);
962*f4a2713aSLionel Sambuc       continue;
963*f4a2713aSLionel Sambuc     }
964*f4a2713aSLionel Sambuc 
965*f4a2713aSLionel Sambuc     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
966*f4a2713aSLionel Sambuc     //  A variable that appears in a private clause must not have an incomplete
967*f4a2713aSLionel Sambuc     //  type or a reference type.
968*f4a2713aSLionel Sambuc     if (RequireCompleteType(ELoc, Type,
969*f4a2713aSLionel Sambuc                             diag::err_omp_firstprivate_incomplete_type)) {
970*f4a2713aSLionel Sambuc       continue;
971*f4a2713aSLionel Sambuc     }
972*f4a2713aSLionel Sambuc     if (Type->isReferenceType()) {
973*f4a2713aSLionel Sambuc       Diag(ELoc, diag::err_omp_clause_ref_type_arg)
974*f4a2713aSLionel Sambuc         << getOpenMPClauseName(OMPC_firstprivate) << Type;
975*f4a2713aSLionel Sambuc       bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
976*f4a2713aSLionel Sambuc                     VarDecl::DeclarationOnly;
977*f4a2713aSLionel Sambuc       Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
978*f4a2713aSLionel Sambuc                                        diag::note_defined_here) << VD;
979*f4a2713aSLionel Sambuc       continue;
980*f4a2713aSLionel Sambuc     }
981*f4a2713aSLionel Sambuc 
982*f4a2713aSLionel Sambuc     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
983*f4a2713aSLionel Sambuc     //  A variable of class type (or array thereof) that appears in a private
984*f4a2713aSLionel Sambuc     //  clause requires an accesible, unambiguous copy constructor for the
985*f4a2713aSLionel Sambuc     //  class type.
986*f4a2713aSLionel Sambuc     Type = Context.getBaseElementType(Type);
987*f4a2713aSLionel Sambuc     CXXRecordDecl *RD = getLangOpts().CPlusPlus ?
988*f4a2713aSLionel Sambuc                           Type.getNonReferenceType()->getAsCXXRecordDecl() : 0;
989*f4a2713aSLionel Sambuc     if (RD) {
990*f4a2713aSLionel Sambuc       CXXConstructorDecl *CD = LookupCopyingConstructor(RD, 0);
991*f4a2713aSLionel Sambuc       PartialDiagnostic PD =
992*f4a2713aSLionel Sambuc         PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
993*f4a2713aSLionel Sambuc       if (!CD ||
994*f4a2713aSLionel Sambuc           CheckConstructorAccess(ELoc, CD,
995*f4a2713aSLionel Sambuc                                  InitializedEntity::InitializeTemporary(Type),
996*f4a2713aSLionel Sambuc                                  CD->getAccess(), PD) == AR_inaccessible ||
997*f4a2713aSLionel Sambuc           CD->isDeleted()) {
998*f4a2713aSLionel Sambuc         Diag(ELoc, diag::err_omp_required_method)
999*f4a2713aSLionel Sambuc              << getOpenMPClauseName(OMPC_firstprivate) << 1;
1000*f4a2713aSLionel Sambuc         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
1001*f4a2713aSLionel Sambuc                       VarDecl::DeclarationOnly;
1002*f4a2713aSLionel Sambuc         Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
1003*f4a2713aSLionel Sambuc                                          diag::note_defined_here) << VD;
1004*f4a2713aSLionel Sambuc         Diag(RD->getLocation(), diag::note_previous_decl) << RD;
1005*f4a2713aSLionel Sambuc         continue;
1006*f4a2713aSLionel Sambuc       }
1007*f4a2713aSLionel Sambuc       MarkFunctionReferenced(ELoc, CD);
1008*f4a2713aSLionel Sambuc       DiagnoseUseOfDecl(CD, ELoc);
1009*f4a2713aSLionel Sambuc 
1010*f4a2713aSLionel Sambuc       CXXDestructorDecl *DD = RD->getDestructor();
1011*f4a2713aSLionel Sambuc       if (DD) {
1012*f4a2713aSLionel Sambuc         if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
1013*f4a2713aSLionel Sambuc             DD->isDeleted()) {
1014*f4a2713aSLionel Sambuc           Diag(ELoc, diag::err_omp_required_method)
1015*f4a2713aSLionel Sambuc                << getOpenMPClauseName(OMPC_firstprivate) << 4;
1016*f4a2713aSLionel Sambuc           bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
1017*f4a2713aSLionel Sambuc                         VarDecl::DeclarationOnly;
1018*f4a2713aSLionel Sambuc           Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl :
1019*f4a2713aSLionel Sambuc                                            diag::note_defined_here) << VD;
1020*f4a2713aSLionel Sambuc           Diag(RD->getLocation(), diag::note_previous_decl) << RD;
1021*f4a2713aSLionel Sambuc           continue;
1022*f4a2713aSLionel Sambuc         }
1023*f4a2713aSLionel Sambuc         MarkFunctionReferenced(ELoc, DD);
1024*f4a2713aSLionel Sambuc         DiagnoseUseOfDecl(DD, ELoc);
1025*f4a2713aSLionel Sambuc       }
1026*f4a2713aSLionel Sambuc     }
1027*f4a2713aSLionel Sambuc 
1028*f4a2713aSLionel Sambuc     // If StartLoc and EndLoc are invalid - this is an implicit firstprivate
1029*f4a2713aSLionel Sambuc     // variable and it was checked already.
1030*f4a2713aSLionel Sambuc     if (StartLoc.isValid() && EndLoc.isValid()) {
1031*f4a2713aSLionel Sambuc       DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
1032*f4a2713aSLionel Sambuc       Type = Type.getNonReferenceType().getCanonicalType();
1033*f4a2713aSLionel Sambuc       bool IsConstant = Type.isConstant(Context);
1034*f4a2713aSLionel Sambuc       Type = Context.getBaseElementType(Type);
1035*f4a2713aSLionel Sambuc       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
1036*f4a2713aSLionel Sambuc       //  A list item that specifies a given variable may not appear in more
1037*f4a2713aSLionel Sambuc       // than one clause on the same directive, except that a variable may be
1038*f4a2713aSLionel Sambuc       //  specified in both firstprivate and lastprivate clauses.
1039*f4a2713aSLionel Sambuc       //  TODO: add processing for lastprivate.
1040*f4a2713aSLionel Sambuc       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
1041*f4a2713aSLionel Sambuc           DVar.RefExpr) {
1042*f4a2713aSLionel Sambuc         Diag(ELoc, diag::err_omp_wrong_dsa)
1043*f4a2713aSLionel Sambuc            << getOpenMPClauseName(DVar.CKind)
1044*f4a2713aSLionel Sambuc            << getOpenMPClauseName(OMPC_firstprivate);
1045*f4a2713aSLionel Sambuc         Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1046*f4a2713aSLionel Sambuc            << getOpenMPClauseName(DVar.CKind);
1047*f4a2713aSLionel Sambuc         continue;
1048*f4a2713aSLionel Sambuc       }
1049*f4a2713aSLionel Sambuc 
1050*f4a2713aSLionel Sambuc       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1051*f4a2713aSLionel Sambuc       // in a Construct]
1052*f4a2713aSLionel Sambuc       //  Variables with the predetermined data-sharing attributes may not be
1053*f4a2713aSLionel Sambuc       //  listed in data-sharing attributes clauses, except for the cases
1054*f4a2713aSLionel Sambuc       //  listed below. For these exceptions only, listing a predetermined
1055*f4a2713aSLionel Sambuc       //  variable in a data-sharing attribute clause is allowed and overrides
1056*f4a2713aSLionel Sambuc       //  the variable's predetermined data-sharing attributes.
1057*f4a2713aSLionel Sambuc       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1058*f4a2713aSLionel Sambuc       // in a Construct, C/C++, p.2]
1059*f4a2713aSLionel Sambuc       //  Variables with const-qualified type having no mutable member may be
1060*f4a2713aSLionel Sambuc       //  listed in a firstprivate clause, even if they are static data members.
1061*f4a2713aSLionel Sambuc       if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr &&
1062*f4a2713aSLionel Sambuc           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
1063*f4a2713aSLionel Sambuc         Diag(ELoc, diag::err_omp_wrong_dsa)
1064*f4a2713aSLionel Sambuc            << getOpenMPClauseName(DVar.CKind)
1065*f4a2713aSLionel Sambuc            << getOpenMPClauseName(OMPC_firstprivate);
1066*f4a2713aSLionel Sambuc         Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
1067*f4a2713aSLionel Sambuc            << getOpenMPClauseName(DVar.CKind);
1068*f4a2713aSLionel Sambuc         continue;
1069*f4a2713aSLionel Sambuc       }
1070*f4a2713aSLionel Sambuc 
1071*f4a2713aSLionel Sambuc       // OpenMP [2.9.3.4, Restrictions, p.2]
1072*f4a2713aSLionel Sambuc       //  A list item that is private within a parallel region must not appear
1073*f4a2713aSLionel Sambuc       //  in a firstprivate clause on a worksharing construct if any of the
1074*f4a2713aSLionel Sambuc       //  worksharing regions arising from the worksharing construct ever bind
1075*f4a2713aSLionel Sambuc       //  to any of the parallel regions arising from the parallel construct.
1076*f4a2713aSLionel Sambuc       // OpenMP [2.9.3.4, Restrictions, p.3]
1077*f4a2713aSLionel Sambuc       //  A list item that appears in a reduction clause of a parallel construct
1078*f4a2713aSLionel Sambuc       //  must not appear in a firstprivate clause on a worksharing or task
1079*f4a2713aSLionel Sambuc       //  construct if any of the worksharing or task regions arising from the
1080*f4a2713aSLionel Sambuc       //  worksharing or task construct ever bind to any of the parallel regions
1081*f4a2713aSLionel Sambuc       //  arising from the parallel construct.
1082*f4a2713aSLionel Sambuc       // OpenMP [2.9.3.4, Restrictions, p.4]
1083*f4a2713aSLionel Sambuc       //  A list item that appears in a reduction clause in worksharing
1084*f4a2713aSLionel Sambuc       //  construct must not appear in a firstprivate clause in a task construct
1085*f4a2713aSLionel Sambuc       //  encountered during execution of any of the worksharing regions arising
1086*f4a2713aSLionel Sambuc       //  from the worksharing construct.
1087*f4a2713aSLionel Sambuc       // TODO:
1088*f4a2713aSLionel Sambuc     }
1089*f4a2713aSLionel Sambuc 
1090*f4a2713aSLionel Sambuc     DSAStack->addDSA(VD, DE, OMPC_firstprivate);
1091*f4a2713aSLionel Sambuc     Vars.push_back(DE);
1092*f4a2713aSLionel Sambuc   }
1093*f4a2713aSLionel Sambuc 
1094*f4a2713aSLionel Sambuc   if (Vars.empty()) return 0;
1095*f4a2713aSLionel Sambuc 
1096*f4a2713aSLionel Sambuc   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
1097*f4a2713aSLionel Sambuc                                        Vars);
1098*f4a2713aSLionel Sambuc }
1099*f4a2713aSLionel Sambuc 
1100*f4a2713aSLionel Sambuc OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
1101*f4a2713aSLionel Sambuc                                          SourceLocation StartLoc,
1102*f4a2713aSLionel Sambuc                                          SourceLocation LParenLoc,
1103*f4a2713aSLionel Sambuc                                          SourceLocation EndLoc) {
1104*f4a2713aSLionel Sambuc   SmallVector<Expr *, 8> Vars;
1105*f4a2713aSLionel Sambuc   for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end();
1106*f4a2713aSLionel Sambuc        I != E; ++I) {
1107*f4a2713aSLionel Sambuc     assert(*I && "NULL expr in OpenMP shared clause.");
1108*f4a2713aSLionel Sambuc     if (isa<DependentScopeDeclRefExpr>(*I)) {
1109*f4a2713aSLionel Sambuc       // It will be analyzed later.
1110*f4a2713aSLionel Sambuc       Vars.push_back(*I);
1111*f4a2713aSLionel Sambuc       continue;
1112*f4a2713aSLionel Sambuc     }
1113*f4a2713aSLionel Sambuc 
1114*f4a2713aSLionel Sambuc     SourceLocation ELoc = (*I)->getExprLoc();
1115*f4a2713aSLionel Sambuc     // OpenMP [2.1, C/C++]
1116*f4a2713aSLionel Sambuc     //  A list item is a variable name.
1117*f4a2713aSLionel Sambuc     // OpenMP  [2.9.3.4, Restrictions, p.1]
1118*f4a2713aSLionel Sambuc     //  A variable that is part of another variable (as an array or
1119*f4a2713aSLionel Sambuc     //  structure element) cannot appear in a private clause.
1120*f4a2713aSLionel Sambuc     DeclRefExpr *DE = dyn_cast<DeclRefExpr>(*I);
1121*f4a2713aSLionel Sambuc     if (!DE || !isa<VarDecl>(DE->getDecl())) {
1122*f4a2713aSLionel Sambuc       Diag(ELoc, diag::err_omp_expected_var_name)
1123*f4a2713aSLionel Sambuc         << (*I)->getSourceRange();
1124*f4a2713aSLionel Sambuc       continue;
1125*f4a2713aSLionel Sambuc     }
1126*f4a2713aSLionel Sambuc     Decl *D = DE->getDecl();
1127*f4a2713aSLionel Sambuc     VarDecl *VD = cast<VarDecl>(D);
1128*f4a2713aSLionel Sambuc 
1129*f4a2713aSLionel Sambuc     QualType Type = VD->getType();
1130*f4a2713aSLionel Sambuc     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
1131*f4a2713aSLionel Sambuc       // It will be analyzed later.
1132*f4a2713aSLionel Sambuc       Vars.push_back(DE);
1133*f4a2713aSLionel Sambuc       continue;
1134*f4a2713aSLionel Sambuc     }
1135*f4a2713aSLionel Sambuc 
1136*f4a2713aSLionel Sambuc     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1137*f4a2713aSLionel Sambuc     // in a Construct]
1138*f4a2713aSLionel Sambuc     //  Variables with the predetermined data-sharing attributes may not be
1139*f4a2713aSLionel Sambuc     //  listed in data-sharing attributes clauses, except for the cases
1140*f4a2713aSLionel Sambuc     //  listed below. For these exceptions only, listing a predetermined
1141*f4a2713aSLionel Sambuc     //  variable in a data-sharing attribute clause is allowed and overrides
1142*f4a2713aSLionel Sambuc     //  the variable's predetermined data-sharing attributes.
1143*f4a2713aSLionel Sambuc     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
1144*f4a2713aSLionel Sambuc     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && DVar.RefExpr) {
1145*f4a2713aSLionel Sambuc       Diag(ELoc, diag::err_omp_wrong_dsa)
1146*f4a2713aSLionel Sambuc          << getOpenMPClauseName(DVar.CKind)
1147*f4a2713aSLionel Sambuc          << getOpenMPClauseName(OMPC_shared);
1148*f4a2713aSLionel Sambuc       Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1149*f4a2713aSLionel Sambuc            << getOpenMPClauseName(DVar.CKind);
1150*f4a2713aSLionel Sambuc       continue;
1151*f4a2713aSLionel Sambuc     }
1152*f4a2713aSLionel Sambuc 
1153*f4a2713aSLionel Sambuc     DSAStack->addDSA(VD, DE, OMPC_shared);
1154*f4a2713aSLionel Sambuc     Vars.push_back(DE);
1155*f4a2713aSLionel Sambuc   }
1156*f4a2713aSLionel Sambuc 
1157*f4a2713aSLionel Sambuc   if (Vars.empty()) return 0;
1158*f4a2713aSLionel Sambuc 
1159*f4a2713aSLionel Sambuc   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
1160*f4a2713aSLionel Sambuc }
1161*f4a2713aSLionel Sambuc 
1162*f4a2713aSLionel Sambuc #undef DSAStack
1163