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