1249261Sdim//===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ----------===// 2249261Sdim// 3249261Sdim// The LLVM Compiler Infrastructure 4249261Sdim// 5249261Sdim// This file is distributed under the University of Illinois Open Source 6249261Sdim// License. See LICENSE.TXT for details. 7249261Sdim// 8249261Sdim//===----------------------------------------------------------------------===// 9249261Sdim/// \file 10249261Sdim/// \brief This file implements semantic analysis for OpenMP directives and 11263508Sdim/// clauses. 12249261Sdim/// 13249261Sdim//===----------------------------------------------------------------------===// 14249261Sdim 15249261Sdim#include "clang/Basic/OpenMPKinds.h" 16249261Sdim#include "clang/AST/Decl.h" 17263508Sdim#include "clang/AST/DeclCXX.h" 18249261Sdim#include "clang/AST/DeclOpenMP.h" 19263508Sdim#include "clang/AST/StmtCXX.h" 20263508Sdim#include "clang/AST/StmtOpenMP.h" 21263508Sdim#include "clang/AST/StmtVisitor.h" 22249261Sdim#include "clang/Lex/Preprocessor.h" 23263508Sdim#include "clang/Sema/Initialization.h" 24249261Sdim#include "clang/Sema/SemaInternal.h" 25249261Sdim#include "clang/Sema/Lookup.h" 26263508Sdim#include "clang/Sema/Scope.h" 27263508Sdim#include "clang/Sema/ScopeInfo.h" 28249261Sdimusing namespace clang; 29249261Sdim 30263508Sdim//===----------------------------------------------------------------------===// 31263508Sdim// Stack of data-sharing attributes for variables 32263508Sdim//===----------------------------------------------------------------------===// 33263508Sdim 34249261Sdimnamespace { 35263508Sdim/// \brief Default data sharing attributes, which can be applied to directive. 36263508Sdimenum DefaultDataSharingAttributes { 37263508Sdim DSA_unspecified = 0, /// \brief Data sharing attribute not specified. 38263508Sdim DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'. 39263508Sdim DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'. 40263508Sdim}; 41249261Sdim 42263508Sdim/// \brief Stack for tracking declarations used in OpenMP directives and 43263508Sdim/// clauses and their data-sharing attributes. 44263508Sdimclass DSAStackTy { 45263508Sdimpublic: 46263508Sdim struct DSAVarData { 47263508Sdim OpenMPDirectiveKind DKind; 48263508Sdim OpenMPClauseKind CKind; 49263508Sdim DeclRefExpr *RefExpr; 50263508Sdim DSAVarData() : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(0) { } 51263508Sdim }; 52263508Sdimprivate: 53263508Sdim struct DSAInfo { 54263508Sdim OpenMPClauseKind Attributes; 55263508Sdim DeclRefExpr *RefExpr; 56263508Sdim }; 57263508Sdim typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy; 58263508Sdim 59263508Sdim struct SharingMapTy { 60263508Sdim DeclSAMapTy SharingMap; 61263508Sdim DefaultDataSharingAttributes DefaultAttr; 62263508Sdim OpenMPDirectiveKind Directive; 63263508Sdim DeclarationNameInfo DirectiveName; 64263508Sdim Scope *CurScope; 65263508Sdim SharingMapTy(OpenMPDirectiveKind DKind, 66263508Sdim const DeclarationNameInfo &Name, 67263508Sdim Scope *CurScope) 68263508Sdim : SharingMap(), DefaultAttr(DSA_unspecified), Directive(DKind), 69263508Sdim DirectiveName(Name), CurScope(CurScope) { } 70263508Sdim SharingMapTy() 71263508Sdim : SharingMap(), DefaultAttr(DSA_unspecified), 72263508Sdim Directive(OMPD_unknown), DirectiveName(), 73263508Sdim CurScope(0) { } 74263508Sdim }; 75263508Sdim 76263508Sdim typedef SmallVector<SharingMapTy, 64> StackTy; 77263508Sdim 78263508Sdim /// \brief Stack of used declaration and their data-sharing attributes. 79263508Sdim StackTy Stack; 80263508Sdim Sema &Actions; 81263508Sdim 82263508Sdim typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; 83263508Sdim 84263508Sdim DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D); 85263508Sdimpublic: 86263508Sdim explicit DSAStackTy(Sema &S) : Stack(1), Actions(S) { } 87263508Sdim 88263508Sdim void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 89263508Sdim Scope *CurScope) { 90263508Sdim Stack.push_back(SharingMapTy(DKind, DirName, CurScope)); 91263508Sdim } 92263508Sdim 93263508Sdim void pop() { 94263508Sdim assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!"); 95263508Sdim Stack.pop_back(); 96263508Sdim } 97263508Sdim 98263508Sdim /// \brief Adds explicit data sharing attribute to the specified declaration. 99263508Sdim void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A); 100263508Sdim 101263508Sdim /// \brief Checks if the variable is a local for OpenMP region. 102263508Sdim bool isOpenMPLocal(VarDecl *D); 103263508Sdim 104263508Sdim /// \brief Returns data sharing attributes from top of the stack for the 105263508Sdim /// specified declaration. 106263508Sdim DSAVarData getTopDSA(VarDecl *D); 107263508Sdim /// \brief Returns data-sharing attributes for the specified declaration. 108263508Sdim DSAVarData getImplicitDSA(VarDecl *D); 109263508Sdim /// \brief Checks if the specified variables has \a CKind data-sharing 110263508Sdim /// attribute in \a DKind directive. 111263508Sdim DSAVarData hasDSA(VarDecl *D, OpenMPClauseKind CKind, 112263508Sdim OpenMPDirectiveKind DKind = OMPD_unknown); 113263508Sdim 114263508Sdim 115263508Sdim /// \brief Returns currently analyzed directive. 116263508Sdim OpenMPDirectiveKind getCurrentDirective() const { 117263508Sdim return Stack.back().Directive; 118263508Sdim } 119263508Sdim 120263508Sdim /// \brief Set default data sharing attribute to none. 121263508Sdim void setDefaultDSANone() { Stack.back().DefaultAttr = DSA_none; } 122263508Sdim /// \brief Set default data sharing attribute to shared. 123263508Sdim void setDefaultDSAShared() { Stack.back().DefaultAttr = DSA_shared; } 124263508Sdim 125263508Sdim DefaultDataSharingAttributes getDefaultDSA() const { 126263508Sdim return Stack.back().DefaultAttr; 127263508Sdim } 128263508Sdim 129263508Sdim Scope *getCurScope() { return Stack.back().CurScope; } 130263508Sdim}; 131263508Sdim} // end anonymous namespace. 132263508Sdim 133263508SdimDSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter, 134263508Sdim VarDecl *D) { 135263508Sdim DSAVarData DVar; 136263508Sdim if (Iter == Stack.rend() - 1) { 137263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 138263508Sdim // in a region but not in construct] 139263508Sdim // File-scope or namespace-scope variables referenced in called routines 140263508Sdim // in the region are shared unless they appear in a threadprivate 141263508Sdim // directive. 142263508Sdim // TODO 143263508Sdim if (!D->isFunctionOrMethodVarDecl()) 144263508Sdim DVar.CKind = OMPC_shared; 145263508Sdim 146263508Sdim // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 147263508Sdim // in a region but not in construct] 148263508Sdim // Variables with static storage duration that are declared in called 149263508Sdim // routines in the region are shared. 150263508Sdim if (D->hasGlobalStorage()) 151263508Sdim DVar.CKind = OMPC_shared; 152263508Sdim 153263508Sdim return DVar; 154263508Sdim } 155263508Sdim DVar.DKind = Iter->Directive; 156263508Sdim // Explicitly specified attributes and local variables with predetermined 157263508Sdim // attributes. 158263508Sdim if (Iter->SharingMap.count(D)) { 159263508Sdim DVar.RefExpr = Iter->SharingMap[D].RefExpr; 160263508Sdim DVar.CKind = Iter->SharingMap[D].Attributes; 161263508Sdim return DVar; 162263508Sdim } 163263508Sdim 164263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 165263508Sdim // in a Construct, C/C++, implicitly determined, p.1] 166263508Sdim // In a parallel or task construct, the data-sharing attributes of these 167263508Sdim // variables are determined by the default clause, if present. 168263508Sdim switch (Iter->DefaultAttr) { 169263508Sdim case DSA_shared: 170263508Sdim DVar.CKind = OMPC_shared; 171263508Sdim return DVar; 172263508Sdim case DSA_none: 173263508Sdim return DVar; 174263508Sdim case DSA_unspecified: 175263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 176263508Sdim // in a Construct, implicitly determined, p.2] 177263508Sdim // In a parallel construct, if no default clause is present, these 178263508Sdim // variables are shared. 179263508Sdim if (DVar.DKind == OMPD_parallel) { 180263508Sdim DVar.CKind = OMPC_shared; 181263508Sdim return DVar; 182263508Sdim } 183263508Sdim 184263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 185263508Sdim // in a Construct, implicitly determined, p.4] 186263508Sdim // In a task construct, if no default clause is present, a variable that in 187263508Sdim // the enclosing context is determined to be shared by all implicit tasks 188263508Sdim // bound to the current team is shared. 189263508Sdim // TODO 190263508Sdim if (DVar.DKind == OMPD_task) { 191263508Sdim DSAVarData DVarTemp; 192263508Sdim for (StackTy::reverse_iterator I = Iter + 1, 193263508Sdim EE = Stack.rend() - 1; 194263508Sdim I != EE; ++I) { 195263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 196263508Sdim // in a Construct, implicitly determined, p.6] 197263508Sdim // In a task construct, if no default clause is present, a variable 198263508Sdim // whose data-sharing attribute is not determined by the rules above is 199263508Sdim // firstprivate. 200263508Sdim DVarTemp = getDSA(I, D); 201263508Sdim if (DVarTemp.CKind != OMPC_shared) { 202263508Sdim DVar.RefExpr = 0; 203263508Sdim DVar.DKind = OMPD_task; 204263508Sdim DVar.CKind = OMPC_firstprivate; 205263508Sdim return DVar; 206249261Sdim } 207263508Sdim if (I->Directive == OMPD_parallel) break; 208249261Sdim } 209263508Sdim DVar.DKind = OMPD_task; 210263508Sdim DVar.CKind = 211263508Sdim (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 212263508Sdim return DVar; 213263508Sdim } 214263508Sdim } 215263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 216263508Sdim // in a Construct, implicitly determined, p.3] 217263508Sdim // For constructs other than task, if no default clause is present, these 218263508Sdim // variables inherit their data-sharing attributes from the enclosing 219263508Sdim // context. 220263508Sdim return getDSA(Iter + 1, D); 221249261Sdim} 222263508Sdim 223263508Sdimvoid DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) { 224263508Sdim if (A == OMPC_threadprivate) { 225263508Sdim Stack[0].SharingMap[D].Attributes = A; 226263508Sdim Stack[0].SharingMap[D].RefExpr = E; 227263508Sdim } else { 228263508Sdim assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 229263508Sdim Stack.back().SharingMap[D].Attributes = A; 230263508Sdim Stack.back().SharingMap[D].RefExpr = E; 231263508Sdim } 232263508Sdim} 233263508Sdim 234263508Sdimbool DSAStackTy::isOpenMPLocal(VarDecl *D) { 235263508Sdim Scope *CurScope = getCurScope(); 236263508Sdim while (CurScope && !CurScope->isDeclScope(D)) 237263508Sdim CurScope = CurScope->getParent(); 238263508Sdim while (CurScope && !CurScope->isOpenMPDirectiveScope()) 239263508Sdim CurScope = CurScope->getParent(); 240263508Sdim bool isOpenMPLocal = !!CurScope; 241263508Sdim if (!isOpenMPLocal) { 242263508Sdim CurScope = getCurScope(); 243263508Sdim while (CurScope && !CurScope->isOpenMPDirectiveScope()) 244263508Sdim CurScope = CurScope->getParent(); 245263508Sdim isOpenMPLocal = 246263508Sdim CurScope && 247263508Sdim isa<CapturedDecl>(D->getDeclContext()) && 248263508Sdim CurScope->getFnParent()->getEntity()->Encloses(D->getDeclContext()); 249263508Sdim } 250263508Sdim return isOpenMPLocal; 251263508Sdim} 252263508Sdim 253263508SdimDSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D) { 254263508Sdim DSAVarData DVar; 255263508Sdim 256263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 257263508Sdim // in a Construct, C/C++, predetermined, p.1] 258263508Sdim // Variables appearing in threadprivate directives are threadprivate. 259263508Sdim if (D->getTLSKind() != VarDecl::TLS_None) { 260263508Sdim DVar.CKind = OMPC_threadprivate; 261263508Sdim return DVar; 262263508Sdim } 263263508Sdim if (Stack[0].SharingMap.count(D)) { 264263508Sdim DVar.RefExpr = Stack[0].SharingMap[D].RefExpr; 265263508Sdim DVar.CKind = OMPC_threadprivate; 266263508Sdim return DVar; 267263508Sdim } 268263508Sdim 269263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 270263508Sdim // in a Construct, C/C++, predetermined, p.1] 271263508Sdim // Variables with automatic storage duration that are declared in a scope 272263508Sdim // inside the construct are private. 273263508Sdim if (isOpenMPLocal(D) && D->isLocalVarDecl() && 274263508Sdim (D->getStorageClass() == SC_Auto || 275263508Sdim D->getStorageClass() == SC_None)) { 276263508Sdim DVar.CKind = OMPC_private; 277263508Sdim return DVar; 278263508Sdim } 279263508Sdim 280263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 281263508Sdim // in a Construct, C/C++, predetermined, p.4] 282263508Sdim // Static data memebers are shared. 283263508Sdim if (D->isStaticDataMember()) { 284263508Sdim // Variables with const-qualified type having no mutable member may be listed 285263508Sdim // in a firstprivate clause, even if they are static data members. 286263508Sdim DSAVarData DVarTemp = hasDSA(D, OMPC_firstprivate); 287263508Sdim if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 288263508Sdim return DVar; 289263508Sdim 290263508Sdim DVar.CKind = OMPC_shared; 291263508Sdim return DVar; 292263508Sdim } 293263508Sdim 294263508Sdim QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 295263508Sdim bool IsConstant = Type.isConstant(Actions.getASTContext()); 296263508Sdim while (Type->isArrayType()) { 297263508Sdim QualType ElemType = cast<ArrayType>(Type.getTypePtr())->getElementType(); 298263508Sdim Type = ElemType.getNonReferenceType().getCanonicalType(); 299263508Sdim } 300263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 301263508Sdim // in a Construct, C/C++, predetermined, p.6] 302263508Sdim // Variables with const qualified type having no mutable member are 303263508Sdim // shared. 304263508Sdim CXXRecordDecl *RD = Actions.getLangOpts().CPlusPlus ? 305263508Sdim Type->getAsCXXRecordDecl() : 0; 306263508Sdim if (IsConstant && 307263508Sdim !(Actions.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) { 308263508Sdim // Variables with const-qualified type having no mutable member may be 309263508Sdim // listed in a firstprivate clause, even if they are static data members. 310263508Sdim DSAVarData DVarTemp = hasDSA(D, OMPC_firstprivate); 311263508Sdim if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 312263508Sdim return DVar; 313263508Sdim 314263508Sdim DVar.CKind = OMPC_shared; 315263508Sdim return DVar; 316263508Sdim } 317263508Sdim 318263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 319263508Sdim // in a Construct, C/C++, predetermined, p.7] 320263508Sdim // Variables with static storage duration that are declared in a scope 321263508Sdim // inside the construct are shared. 322263508Sdim if (isOpenMPLocal(D) && D->isStaticLocal()) { 323263508Sdim DVar.CKind = OMPC_shared; 324263508Sdim return DVar; 325263508Sdim } 326263508Sdim 327263508Sdim // Explicitly specified attributes and local variables with predetermined 328263508Sdim // attributes. 329263508Sdim if (Stack.back().SharingMap.count(D)) { 330263508Sdim DVar.RefExpr = Stack.back().SharingMap[D].RefExpr; 331263508Sdim DVar.CKind = Stack.back().SharingMap[D].Attributes; 332263508Sdim } 333263508Sdim 334263508Sdim return DVar; 335263508Sdim} 336263508Sdim 337263508SdimDSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D) { 338263508Sdim return getDSA(Stack.rbegin() + 1, D); 339263508Sdim} 340263508Sdim 341263508SdimDSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, OpenMPClauseKind CKind, 342263508Sdim OpenMPDirectiveKind DKind) { 343263508Sdim for (StackTy::reverse_iterator I = Stack.rbegin() + 1, 344263508Sdim E = Stack.rend() - 1; 345249261Sdim I != E; ++I) { 346263508Sdim if (DKind != OMPD_unknown && DKind != I->Directive) continue; 347263508Sdim DSAVarData DVar = getDSA(I, D); 348263508Sdim if (DVar.CKind == CKind) 349263508Sdim return DVar; 350263508Sdim } 351263508Sdim return DSAVarData(); 352263508Sdim} 353249261Sdim 354263508Sdimvoid Sema::InitDataSharingAttributesStack() { 355263508Sdim VarDataSharingAttributesStack = new DSAStackTy(*this); 356263508Sdim} 357249261Sdim 358263508Sdim#define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 359263508Sdim 360263508Sdimvoid Sema::DestroyDataSharingAttributesStack() { 361263508Sdim delete DSAStack; 362263508Sdim} 363263508Sdim 364263508Sdimvoid Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 365263508Sdim const DeclarationNameInfo &DirName, 366263508Sdim Scope *CurScope) { 367263508Sdim DSAStack->push(DKind, DirName, CurScope); 368263508Sdim PushExpressionEvaluationContext(PotentiallyEvaluated); 369263508Sdim} 370263508Sdim 371263508Sdimvoid Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 372263508Sdim DSAStack->pop(); 373263508Sdim DiscardCleanupsInEvaluationContext(); 374263508Sdim PopExpressionEvaluationContext(); 375263508Sdim} 376263508Sdim 377263508Sdimnamespace { 378263508Sdim 379263508Sdimclass VarDeclFilterCCC : public CorrectionCandidateCallback { 380263508Sdimprivate: 381263508Sdim Sema &Actions; 382263508Sdimpublic: 383263508Sdim VarDeclFilterCCC(Sema &S) : Actions(S) { } 384263508Sdim virtual bool ValidateCandidate(const TypoCorrection &Candidate) { 385263508Sdim NamedDecl *ND = Candidate.getCorrectionDecl(); 386263508Sdim if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) { 387263508Sdim return VD->hasGlobalStorage() && 388263508Sdim Actions.isDeclInScope(ND, Actions.getCurLexicalContext(), 389263508Sdim Actions.getCurScope()); 390263508Sdim } 391263508Sdim return false; 392263508Sdim } 393263508Sdim}; 394263508Sdim} 395263508Sdim 396263508SdimExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 397263508Sdim CXXScopeSpec &ScopeSpec, 398263508Sdim const DeclarationNameInfo &Id) { 399263508Sdim LookupResult Lookup(*this, Id, LookupOrdinaryName); 400263508Sdim LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 401263508Sdim 402263508Sdim if (Lookup.isAmbiguous()) 403263508Sdim return ExprError(); 404263508Sdim 405263508Sdim VarDecl *VD; 406263508Sdim if (!Lookup.isSingleResult()) { 407263508Sdim VarDeclFilterCCC Validator(*this); 408263508Sdim if (TypoCorrection Corrected = CorrectTypo(Id, LookupOrdinaryName, CurScope, 409263508Sdim 0, Validator)) { 410263508Sdim diagnoseTypo(Corrected, 411263508Sdim PDiag(Lookup.empty()? diag::err_undeclared_var_use_suggest 412263508Sdim : diag::err_omp_expected_var_arg_suggest) 413263508Sdim << Id.getName()); 414249261Sdim VD = Corrected.getCorrectionDeclAs<VarDecl>(); 415249261Sdim } else { 416263508Sdim Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 417263508Sdim : diag::err_omp_expected_var_arg) 418263508Sdim << Id.getName(); 419263508Sdim return ExprError(); 420249261Sdim } 421263508Sdim } else { 422263508Sdim if (!(VD = Lookup.getAsSingle<VarDecl>())) { 423263508Sdim Diag(Id.getLoc(), diag::err_omp_expected_var_arg) 424263508Sdim << Id.getName(); 425263508Sdim Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 426263508Sdim return ExprError(); 427249261Sdim } 428263508Sdim } 429263508Sdim Lookup.suppressDiagnostics(); 430249261Sdim 431263508Sdim // OpenMP [2.9.2, Syntax, C/C++] 432263508Sdim // Variables must be file-scope, namespace-scope, or static block-scope. 433263508Sdim if (!VD->hasGlobalStorage()) { 434263508Sdim Diag(Id.getLoc(), diag::err_omp_global_var_arg) 435263508Sdim << getOpenMPDirectiveName(OMPD_threadprivate) 436263508Sdim << !VD->isStaticLocal(); 437263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 438263508Sdim VarDecl::DeclarationOnly; 439263508Sdim Diag(VD->getLocation(), 440263508Sdim IsDecl ? diag::note_previous_decl : diag::note_defined_here) << VD; 441263508Sdim return ExprError(); 442263508Sdim } 443249261Sdim 444263508Sdim VarDecl *CanonicalVD = VD->getCanonicalDecl(); 445263508Sdim NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 446263508Sdim // OpenMP [2.9.2, Restrictions, C/C++, p.2] 447263508Sdim // A threadprivate directive for file-scope variables must appear outside 448263508Sdim // any definition or declaration. 449263508Sdim if (CanonicalVD->getDeclContext()->isTranslationUnit() && 450263508Sdim !getCurLexicalContext()->isTranslationUnit()) { 451263508Sdim Diag(Id.getLoc(), diag::err_omp_var_scope) 452263508Sdim << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 453263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 454263508Sdim VarDecl::DeclarationOnly; 455263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 456263508Sdim diag::note_defined_here) << VD; 457263508Sdim return ExprError(); 458263508Sdim } 459263508Sdim // OpenMP [2.9.2, Restrictions, C/C++, p.3] 460263508Sdim // A threadprivate directive for static class member variables must appear 461263508Sdim // in the class definition, in the same scope in which the member 462263508Sdim // variables are declared. 463263508Sdim if (CanonicalVD->isStaticDataMember() && 464263508Sdim !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 465263508Sdim Diag(Id.getLoc(), diag::err_omp_var_scope) 466263508Sdim << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 467263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 468263508Sdim VarDecl::DeclarationOnly; 469263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 470263508Sdim diag::note_defined_here) << VD; 471263508Sdim return ExprError(); 472263508Sdim } 473263508Sdim // OpenMP [2.9.2, Restrictions, C/C++, p.4] 474263508Sdim // A threadprivate directive for namespace-scope variables must appear 475263508Sdim // outside any definition or declaration other than the namespace 476263508Sdim // definition itself. 477263508Sdim if (CanonicalVD->getDeclContext()->isNamespace() && 478263508Sdim (!getCurLexicalContext()->isFileContext() || 479263508Sdim !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 480263508Sdim Diag(Id.getLoc(), diag::err_omp_var_scope) 481263508Sdim << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 482263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 483263508Sdim VarDecl::DeclarationOnly; 484263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 485263508Sdim diag::note_defined_here) << VD; 486263508Sdim return ExprError(); 487263508Sdim } 488263508Sdim // OpenMP [2.9.2, Restrictions, C/C++, p.6] 489263508Sdim // A threadprivate directive for static block-scope variables must appear 490263508Sdim // in the scope of the variable and not in a nested scope. 491263508Sdim if (CanonicalVD->isStaticLocal() && CurScope && 492263508Sdim !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 493263508Sdim Diag(Id.getLoc(), diag::err_omp_var_scope) 494263508Sdim << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 495263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 496263508Sdim VarDecl::DeclarationOnly; 497263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 498263508Sdim diag::note_defined_here) << VD; 499263508Sdim return ExprError(); 500263508Sdim } 501249261Sdim 502263508Sdim // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 503263508Sdim // A threadprivate directive must lexically precede all references to any 504263508Sdim // of the variables in its list. 505263508Sdim if (VD->isUsed()) { 506263508Sdim Diag(Id.getLoc(), diag::err_omp_var_used) 507263508Sdim << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 508263508Sdim return ExprError(); 509249261Sdim } 510263508Sdim 511263508Sdim QualType ExprType = VD->getType().getNonReferenceType(); 512263508Sdim ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_RValue, Id.getLoc()); 513263508Sdim DSAStack->addDSA(VD, cast<DeclRefExpr>(DE.get()), OMPC_threadprivate); 514263508Sdim return DE; 515263508Sdim} 516263508Sdim 517263508SdimSema::DeclGroupPtrTy Sema::ActOnOpenMPThreadprivateDirective( 518263508Sdim SourceLocation Loc, 519263508Sdim ArrayRef<Expr *> VarList) { 520263508Sdim if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 521249261Sdim CurContext->addDecl(D); 522249261Sdim return DeclGroupPtrTy::make(DeclGroupRef(D)); 523249261Sdim } 524249261Sdim return DeclGroupPtrTy(); 525249261Sdim} 526249261Sdim 527249261SdimOMPThreadPrivateDecl *Sema::CheckOMPThreadPrivateDecl( 528249261Sdim SourceLocation Loc, 529263508Sdim ArrayRef<Expr *> VarList) { 530263508Sdim SmallVector<Expr *, 8> Vars; 531263508Sdim for (ArrayRef<Expr *>::iterator I = VarList.begin(), 532249261Sdim E = VarList.end(); 533249261Sdim I != E; ++I) { 534263508Sdim DeclRefExpr *DE = cast<DeclRefExpr>(*I); 535263508Sdim VarDecl *VD = cast<VarDecl>(DE->getDecl()); 536263508Sdim SourceLocation ILoc = DE->getExprLoc(); 537249261Sdim 538249261Sdim // OpenMP [2.9.2, Restrictions, C/C++, p.10] 539249261Sdim // A threadprivate variable must not have an incomplete type. 540249261Sdim if (RequireCompleteType(ILoc, VD->getType(), 541263508Sdim diag::err_omp_threadprivate_incomplete_type)) { 542249261Sdim continue; 543249261Sdim } 544249261Sdim 545249261Sdim // OpenMP [2.9.2, Restrictions, C/C++, p.10] 546249261Sdim // A threadprivate variable must not have a reference type. 547249261Sdim if (VD->getType()->isReferenceType()) { 548249261Sdim Diag(ILoc, diag::err_omp_ref_type_arg) 549263508Sdim << getOpenMPDirectiveName(OMPD_threadprivate) 550263508Sdim << VD->getType(); 551263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 552263508Sdim VarDecl::DeclarationOnly; 553263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 554263508Sdim diag::note_defined_here) << VD; 555249261Sdim continue; 556249261Sdim } 557249261Sdim 558251662Sdim // Check if this is a TLS variable. 559251662Sdim if (VD->getTLSKind()) { 560249261Sdim Diag(ILoc, diag::err_omp_var_thread_local) << VD; 561263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 562263508Sdim VarDecl::DeclarationOnly; 563263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 564263508Sdim diag::note_defined_here) << VD; 565249261Sdim continue; 566249261Sdim } 567249261Sdim 568249261Sdim Vars.push_back(*I); 569249261Sdim } 570249261Sdim return Vars.empty() ? 571249261Sdim 0 : OMPThreadPrivateDecl::Create(Context, 572249261Sdim getCurLexicalContext(), 573249261Sdim Loc, Vars); 574249261Sdim} 575263508Sdim 576263508Sdimnamespace { 577263508Sdimclass DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 578263508Sdim DSAStackTy *Stack; 579263508Sdim Sema &Actions; 580263508Sdim bool ErrorFound; 581263508Sdim CapturedStmt *CS; 582263508Sdim llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 583263508Sdimpublic: 584263508Sdim void VisitDeclRefExpr(DeclRefExpr *E) { 585263508Sdim if(VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 586263508Sdim // Skip internally declared variables. 587263508Sdim if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) return; 588263508Sdim 589263508Sdim SourceLocation ELoc = E->getExprLoc(); 590263508Sdim 591263508Sdim OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 592263508Sdim DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD); 593263508Sdim if (DVar.CKind != OMPC_unknown) { 594263508Sdim if (DKind == OMPD_task && DVar.CKind != OMPC_shared && 595263508Sdim DVar.CKind != OMPC_threadprivate && !DVar.RefExpr) 596263508Sdim ImplicitFirstprivate.push_back(DVar.RefExpr); 597263508Sdim return; 598263508Sdim } 599263508Sdim // The default(none) clause requires that each variable that is referenced 600263508Sdim // in the construct, and does not have a predetermined data-sharing 601263508Sdim // attribute, must have its data-sharing attribute explicitly determined 602263508Sdim // by being listed in a data-sharing attribute clause. 603263508Sdim if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 604263508Sdim (DKind == OMPD_parallel || DKind == OMPD_task)) { 605263508Sdim ErrorFound = true; 606263508Sdim Actions.Diag(ELoc, diag::err_omp_no_dsa_for_variable) << VD; 607263508Sdim return; 608263508Sdim } 609263508Sdim 610263508Sdim // OpenMP [2.9.3.6, Restrictions, p.2] 611263508Sdim // A list item that appears in a reduction clause of the innermost 612263508Sdim // enclosing worksharing or parallel construct may not be accessed in an 613263508Sdim // explicit task. 614263508Sdim // TODO: 615263508Sdim 616263508Sdim // Define implicit data-sharing attributes for task. 617263508Sdim DVar = Stack->getImplicitDSA(VD); 618263508Sdim if (DKind == OMPD_task && DVar.CKind != OMPC_shared) 619263508Sdim ImplicitFirstprivate.push_back(DVar.RefExpr); 620263508Sdim } 621263508Sdim } 622263508Sdim void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 623263508Sdim for (ArrayRef<OMPClause *>::iterator I = S->clauses().begin(), 624263508Sdim E = S->clauses().end(); 625263508Sdim I != E; ++I) 626263508Sdim if (OMPClause *C = *I) 627263508Sdim for (StmtRange R = C->children(); R; ++R) 628263508Sdim if (Stmt *Child = *R) 629263508Sdim Visit(Child); 630263508Sdim } 631263508Sdim void VisitStmt(Stmt *S) { 632263508Sdim for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 633263508Sdim I != E; ++I) 634263508Sdim if (Stmt *Child = *I) 635263508Sdim if (!isa<OMPExecutableDirective>(Child)) 636263508Sdim Visit(Child); 637263508Sdim } 638263508Sdim 639263508Sdim bool isErrorFound() { return ErrorFound; } 640263508Sdim ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; } 641263508Sdim 642263508Sdim DSAAttrChecker(DSAStackTy *S, Sema &Actions, CapturedStmt *CS) 643263508Sdim : Stack(S), Actions(Actions), ErrorFound(false), CS(CS) { } 644263508Sdim}; 645263508Sdim} 646263508Sdim 647263508SdimStmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, 648263508Sdim ArrayRef<OMPClause *> Clauses, 649263508Sdim Stmt *AStmt, 650263508Sdim SourceLocation StartLoc, 651263508Sdim SourceLocation EndLoc) { 652263508Sdim assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 653263508Sdim 654263508Sdim StmtResult Res = StmtError(); 655263508Sdim 656263508Sdim // Check default data sharing attributes for referenced variables. 657263508Sdim DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 658263508Sdim DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt()); 659263508Sdim if (DSAChecker.isErrorFound()) 660263508Sdim return StmtError(); 661263508Sdim // Generate list of implicitly defined firstprivate variables. 662263508Sdim llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 663263508Sdim ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 664263508Sdim 665263508Sdim bool ErrorFound = false; 666263508Sdim if (!DSAChecker.getImplicitFirstprivate().empty()) { 667263508Sdim if (OMPClause *Implicit = 668263508Sdim ActOnOpenMPFirstprivateClause(DSAChecker.getImplicitFirstprivate(), 669263508Sdim SourceLocation(), SourceLocation(), 670263508Sdim SourceLocation())) { 671263508Sdim ClausesWithImplicit.push_back(Implicit); 672263508Sdim ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 673263508Sdim DSAChecker.getImplicitFirstprivate().size(); 674263508Sdim } else 675263508Sdim ErrorFound = true; 676263508Sdim } 677263508Sdim 678263508Sdim switch (Kind) { 679263508Sdim case OMPD_parallel: 680263508Sdim Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, 681263508Sdim StartLoc, EndLoc); 682263508Sdim break; 683263508Sdim case OMPD_threadprivate: 684263508Sdim case OMPD_task: 685263508Sdim llvm_unreachable("OpenMP Directive is not allowed"); 686263508Sdim case OMPD_unknown: 687263508Sdim case NUM_OPENMP_DIRECTIVES: 688263508Sdim llvm_unreachable("Unknown OpenMP directive"); 689263508Sdim } 690263508Sdim 691263508Sdim if (ErrorFound) return StmtError(); 692263508Sdim return Res; 693263508Sdim} 694263508Sdim 695263508SdimStmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 696263508Sdim Stmt *AStmt, 697263508Sdim SourceLocation StartLoc, 698263508Sdim SourceLocation EndLoc) { 699263508Sdim getCurFunction()->setHasBranchProtectedScope(); 700263508Sdim 701263508Sdim return Owned(OMPParallelDirective::Create(Context, StartLoc, EndLoc, 702263508Sdim Clauses, AStmt)); 703263508Sdim} 704263508Sdim 705263508SdimOMPClause *Sema::ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, 706263508Sdim unsigned Argument, 707263508Sdim SourceLocation ArgumentLoc, 708263508Sdim SourceLocation StartLoc, 709263508Sdim SourceLocation LParenLoc, 710263508Sdim SourceLocation EndLoc) { 711263508Sdim OMPClause *Res = 0; 712263508Sdim switch (Kind) { 713263508Sdim case OMPC_default: 714263508Sdim Res = 715263508Sdim ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 716263508Sdim ArgumentLoc, StartLoc, LParenLoc, EndLoc); 717263508Sdim break; 718263508Sdim case OMPC_private: 719263508Sdim case OMPC_firstprivate: 720263508Sdim case OMPC_shared: 721263508Sdim case OMPC_threadprivate: 722263508Sdim case OMPC_unknown: 723263508Sdim case NUM_OPENMP_CLAUSES: 724263508Sdim llvm_unreachable("Clause is not allowed."); 725263508Sdim } 726263508Sdim return Res; 727263508Sdim} 728263508Sdim 729263508SdimOMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 730263508Sdim SourceLocation KindKwLoc, 731263508Sdim SourceLocation StartLoc, 732263508Sdim SourceLocation LParenLoc, 733263508Sdim SourceLocation EndLoc) { 734263508Sdim if (Kind == OMPC_DEFAULT_unknown) { 735263508Sdim std::string Values; 736263508Sdim std::string Sep(NUM_OPENMP_DEFAULT_KINDS > 1 ? ", " : ""); 737263508Sdim for (unsigned i = OMPC_DEFAULT_unknown + 1; 738263508Sdim i < NUM_OPENMP_DEFAULT_KINDS; ++i) { 739263508Sdim Values += "'"; 740263508Sdim Values += getOpenMPSimpleClauseTypeName(OMPC_default, i); 741263508Sdim Values += "'"; 742263508Sdim switch (i) { 743263508Sdim case NUM_OPENMP_DEFAULT_KINDS - 2: 744263508Sdim Values += " or "; 745263508Sdim break; 746263508Sdim case NUM_OPENMP_DEFAULT_KINDS - 1: 747263508Sdim break; 748263508Sdim default: 749263508Sdim Values += Sep; 750263508Sdim break; 751263508Sdim } 752263508Sdim } 753263508Sdim Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 754263508Sdim << Values << getOpenMPClauseName(OMPC_default); 755263508Sdim return 0; 756263508Sdim } 757263508Sdim switch (Kind) { 758263508Sdim case OMPC_DEFAULT_none: 759263508Sdim DSAStack->setDefaultDSANone(); 760263508Sdim break; 761263508Sdim case OMPC_DEFAULT_shared: 762263508Sdim DSAStack->setDefaultDSAShared(); 763263508Sdim break; 764263508Sdim default: 765263508Sdim break; 766263508Sdim } 767263508Sdim return new (Context) OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, 768263508Sdim EndLoc); 769263508Sdim} 770263508Sdim 771263508SdimOMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, 772263508Sdim ArrayRef<Expr *> VarList, 773263508Sdim SourceLocation StartLoc, 774263508Sdim SourceLocation LParenLoc, 775263508Sdim SourceLocation EndLoc) { 776263508Sdim OMPClause *Res = 0; 777263508Sdim switch (Kind) { 778263508Sdim case OMPC_private: 779263508Sdim Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 780263508Sdim break; 781263508Sdim case OMPC_firstprivate: 782263508Sdim Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 783263508Sdim break; 784263508Sdim case OMPC_shared: 785263508Sdim Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 786263508Sdim break; 787263508Sdim case OMPC_default: 788263508Sdim case OMPC_threadprivate: 789263508Sdim case OMPC_unknown: 790263508Sdim case NUM_OPENMP_CLAUSES: 791263508Sdim llvm_unreachable("Clause is not allowed."); 792263508Sdim } 793263508Sdim return Res; 794263508Sdim} 795263508Sdim 796263508SdimOMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 797263508Sdim SourceLocation StartLoc, 798263508Sdim SourceLocation LParenLoc, 799263508Sdim SourceLocation EndLoc) { 800263508Sdim SmallVector<Expr *, 8> Vars; 801263508Sdim for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end(); 802263508Sdim I != E; ++I) { 803263508Sdim assert(*I && "NULL expr in OpenMP private clause."); 804263508Sdim if (isa<DependentScopeDeclRefExpr>(*I)) { 805263508Sdim // It will be analyzed later. 806263508Sdim Vars.push_back(*I); 807263508Sdim continue; 808263508Sdim } 809263508Sdim 810263508Sdim SourceLocation ELoc = (*I)->getExprLoc(); 811263508Sdim // OpenMP [2.1, C/C++] 812263508Sdim // A list item is a variable name. 813263508Sdim // OpenMP [2.9.3.3, Restrictions, p.1] 814263508Sdim // A variable that is part of another variable (as an array or 815263508Sdim // structure element) cannot appear in a private clause. 816263508Sdim DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(*I); 817263508Sdim if (!DE || !isa<VarDecl>(DE->getDecl())) { 818263508Sdim Diag(ELoc, diag::err_omp_expected_var_name) 819263508Sdim << (*I)->getSourceRange(); 820263508Sdim continue; 821263508Sdim } 822263508Sdim Decl *D = DE->getDecl(); 823263508Sdim VarDecl *VD = cast<VarDecl>(D); 824263508Sdim 825263508Sdim QualType Type = VD->getType(); 826263508Sdim if (Type->isDependentType() || Type->isInstantiationDependentType()) { 827263508Sdim // It will be analyzed later. 828263508Sdim Vars.push_back(DE); 829263508Sdim continue; 830263508Sdim } 831263508Sdim 832263508Sdim // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 833263508Sdim // A variable that appears in a private clause must not have an incomplete 834263508Sdim // type or a reference type. 835263508Sdim if (RequireCompleteType(ELoc, Type, 836263508Sdim diag::err_omp_private_incomplete_type)) { 837263508Sdim continue; 838263508Sdim } 839263508Sdim if (Type->isReferenceType()) { 840263508Sdim Diag(ELoc, diag::err_omp_clause_ref_type_arg) 841263508Sdim << getOpenMPClauseName(OMPC_private) << Type; 842263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 843263508Sdim VarDecl::DeclarationOnly; 844263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 845263508Sdim diag::note_defined_here) << VD; 846263508Sdim continue; 847263508Sdim } 848263508Sdim 849263508Sdim // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 850263508Sdim // A variable of class type (or array thereof) that appears in a private 851263508Sdim // clause requires an accesible, unambiguous default constructor for the 852263508Sdim // class type. 853263508Sdim while (Type.getNonReferenceType()->isArrayType()) { 854263508Sdim Type = cast<ArrayType>( 855263508Sdim Type.getNonReferenceType().getTypePtr())->getElementType(); 856263508Sdim } 857263508Sdim CXXRecordDecl *RD = getLangOpts().CPlusPlus ? 858263508Sdim Type.getNonReferenceType()->getAsCXXRecordDecl() : 0; 859263508Sdim if (RD) { 860263508Sdim CXXConstructorDecl *CD = LookupDefaultConstructor(RD); 861263508Sdim PartialDiagnostic PD = 862263508Sdim PartialDiagnostic(PartialDiagnostic::NullDiagnostic()); 863263508Sdim if (!CD || 864263508Sdim CheckConstructorAccess(ELoc, CD, 865263508Sdim InitializedEntity::InitializeTemporary(Type), 866263508Sdim CD->getAccess(), PD) == AR_inaccessible || 867263508Sdim CD->isDeleted()) { 868263508Sdim Diag(ELoc, diag::err_omp_required_method) 869263508Sdim << getOpenMPClauseName(OMPC_private) << 0; 870263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 871263508Sdim VarDecl::DeclarationOnly; 872263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 873263508Sdim diag::note_defined_here) << VD; 874263508Sdim Diag(RD->getLocation(), diag::note_previous_decl) << RD; 875263508Sdim continue; 876263508Sdim } 877263508Sdim MarkFunctionReferenced(ELoc, CD); 878263508Sdim DiagnoseUseOfDecl(CD, ELoc); 879263508Sdim 880263508Sdim CXXDestructorDecl *DD = RD->getDestructor(); 881263508Sdim if (DD) { 882263508Sdim if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible || 883263508Sdim DD->isDeleted()) { 884263508Sdim Diag(ELoc, diag::err_omp_required_method) 885263508Sdim << getOpenMPClauseName(OMPC_private) << 4; 886263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 887263508Sdim VarDecl::DeclarationOnly; 888263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 889263508Sdim diag::note_defined_here) << VD; 890263508Sdim Diag(RD->getLocation(), diag::note_previous_decl) << RD; 891263508Sdim continue; 892263508Sdim } 893263508Sdim MarkFunctionReferenced(ELoc, DD); 894263508Sdim DiagnoseUseOfDecl(DD, ELoc); 895263508Sdim } 896263508Sdim } 897263508Sdim 898263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 899263508Sdim // in a Construct] 900263508Sdim // Variables with the predetermined data-sharing attributes may not be 901263508Sdim // listed in data-sharing attributes clauses, except for the cases 902263508Sdim // listed below. For these exceptions only, listing a predetermined 903263508Sdim // variable in a data-sharing attribute clause is allowed and overrides 904263508Sdim // the variable's predetermined data-sharing attributes. 905263508Sdim DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD); 906263508Sdim if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 907263508Sdim Diag(ELoc, diag::err_omp_wrong_dsa) 908263508Sdim << getOpenMPClauseName(DVar.CKind) 909263508Sdim << getOpenMPClauseName(OMPC_private); 910263508Sdim if (DVar.RefExpr) { 911263508Sdim Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 912263508Sdim << getOpenMPClauseName(DVar.CKind); 913263508Sdim } else { 914263508Sdim Diag(VD->getLocation(), diag::note_omp_predetermined_dsa) 915263508Sdim << getOpenMPClauseName(DVar.CKind); 916263508Sdim } 917263508Sdim continue; 918263508Sdim } 919263508Sdim 920263508Sdim DSAStack->addDSA(VD, DE, OMPC_private); 921263508Sdim Vars.push_back(DE); 922263508Sdim } 923263508Sdim 924263508Sdim if (Vars.empty()) return 0; 925263508Sdim 926263508Sdim return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 927263508Sdim} 928263508Sdim 929263508SdimOMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 930263508Sdim SourceLocation StartLoc, 931263508Sdim SourceLocation LParenLoc, 932263508Sdim SourceLocation EndLoc) { 933263508Sdim SmallVector<Expr *, 8> Vars; 934263508Sdim for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end(); 935263508Sdim I != E; ++I) { 936263508Sdim assert(*I && "NULL expr in OpenMP firstprivate clause."); 937263508Sdim if (isa<DependentScopeDeclRefExpr>(*I)) { 938263508Sdim // It will be analyzed later. 939263508Sdim Vars.push_back(*I); 940263508Sdim continue; 941263508Sdim } 942263508Sdim 943263508Sdim SourceLocation ELoc = (*I)->getExprLoc(); 944263508Sdim // OpenMP [2.1, C/C++] 945263508Sdim // A list item is a variable name. 946263508Sdim // OpenMP [2.9.3.3, Restrictions, p.1] 947263508Sdim // A variable that is part of another variable (as an array or 948263508Sdim // structure element) cannot appear in a private clause. 949263508Sdim DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(*I); 950263508Sdim if (!DE || !isa<VarDecl>(DE->getDecl())) { 951263508Sdim Diag(ELoc, diag::err_omp_expected_var_name) 952263508Sdim << (*I)->getSourceRange(); 953263508Sdim continue; 954263508Sdim } 955263508Sdim Decl *D = DE->getDecl(); 956263508Sdim VarDecl *VD = cast<VarDecl>(D); 957263508Sdim 958263508Sdim QualType Type = VD->getType(); 959263508Sdim if (Type->isDependentType() || Type->isInstantiationDependentType()) { 960263508Sdim // It will be analyzed later. 961263508Sdim Vars.push_back(DE); 962263508Sdim continue; 963263508Sdim } 964263508Sdim 965263508Sdim // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 966263508Sdim // A variable that appears in a private clause must not have an incomplete 967263508Sdim // type or a reference type. 968263508Sdim if (RequireCompleteType(ELoc, Type, 969263508Sdim diag::err_omp_firstprivate_incomplete_type)) { 970263508Sdim continue; 971263508Sdim } 972263508Sdim if (Type->isReferenceType()) { 973263508Sdim Diag(ELoc, diag::err_omp_clause_ref_type_arg) 974263508Sdim << getOpenMPClauseName(OMPC_firstprivate) << Type; 975263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 976263508Sdim VarDecl::DeclarationOnly; 977263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 978263508Sdim diag::note_defined_here) << VD; 979263508Sdim continue; 980263508Sdim } 981263508Sdim 982263508Sdim // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 983263508Sdim // A variable of class type (or array thereof) that appears in a private 984263508Sdim // clause requires an accesible, unambiguous copy constructor for the 985263508Sdim // class type. 986263508Sdim Type = Context.getBaseElementType(Type); 987263508Sdim CXXRecordDecl *RD = getLangOpts().CPlusPlus ? 988263508Sdim Type.getNonReferenceType()->getAsCXXRecordDecl() : 0; 989263508Sdim if (RD) { 990263508Sdim CXXConstructorDecl *CD = LookupCopyingConstructor(RD, 0); 991263508Sdim PartialDiagnostic PD = 992263508Sdim PartialDiagnostic(PartialDiagnostic::NullDiagnostic()); 993263508Sdim if (!CD || 994263508Sdim CheckConstructorAccess(ELoc, CD, 995263508Sdim InitializedEntity::InitializeTemporary(Type), 996263508Sdim CD->getAccess(), PD) == AR_inaccessible || 997263508Sdim CD->isDeleted()) { 998263508Sdim Diag(ELoc, diag::err_omp_required_method) 999263508Sdim << getOpenMPClauseName(OMPC_firstprivate) << 1; 1000263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 1001263508Sdim VarDecl::DeclarationOnly; 1002263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 1003263508Sdim diag::note_defined_here) << VD; 1004263508Sdim Diag(RD->getLocation(), diag::note_previous_decl) << RD; 1005263508Sdim continue; 1006263508Sdim } 1007263508Sdim MarkFunctionReferenced(ELoc, CD); 1008263508Sdim DiagnoseUseOfDecl(CD, ELoc); 1009263508Sdim 1010263508Sdim CXXDestructorDecl *DD = RD->getDestructor(); 1011263508Sdim if (DD) { 1012263508Sdim if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible || 1013263508Sdim DD->isDeleted()) { 1014263508Sdim Diag(ELoc, diag::err_omp_required_method) 1015263508Sdim << getOpenMPClauseName(OMPC_firstprivate) << 4; 1016263508Sdim bool IsDecl = VD->isThisDeclarationADefinition(Context) == 1017263508Sdim VarDecl::DeclarationOnly; 1018263508Sdim Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl : 1019263508Sdim diag::note_defined_here) << VD; 1020263508Sdim Diag(RD->getLocation(), diag::note_previous_decl) << RD; 1021263508Sdim continue; 1022263508Sdim } 1023263508Sdim MarkFunctionReferenced(ELoc, DD); 1024263508Sdim DiagnoseUseOfDecl(DD, ELoc); 1025263508Sdim } 1026263508Sdim } 1027263508Sdim 1028263508Sdim // If StartLoc and EndLoc are invalid - this is an implicit firstprivate 1029263508Sdim // variable and it was checked already. 1030263508Sdim if (StartLoc.isValid() && EndLoc.isValid()) { 1031263508Sdim DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD); 1032263508Sdim Type = Type.getNonReferenceType().getCanonicalType(); 1033263508Sdim bool IsConstant = Type.isConstant(Context); 1034263508Sdim Type = Context.getBaseElementType(Type); 1035263508Sdim // OpenMP [2.4.13, Data-sharing Attribute Clauses] 1036263508Sdim // A list item that specifies a given variable may not appear in more 1037263508Sdim // than one clause on the same directive, except that a variable may be 1038263508Sdim // specified in both firstprivate and lastprivate clauses. 1039263508Sdim // TODO: add processing for lastprivate. 1040263508Sdim if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 1041263508Sdim DVar.RefExpr) { 1042263508Sdim Diag(ELoc, diag::err_omp_wrong_dsa) 1043263508Sdim << getOpenMPClauseName(DVar.CKind) 1044263508Sdim << getOpenMPClauseName(OMPC_firstprivate); 1045263508Sdim Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1046263508Sdim << getOpenMPClauseName(DVar.CKind); 1047263508Sdim continue; 1048263508Sdim } 1049263508Sdim 1050263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1051263508Sdim // in a Construct] 1052263508Sdim // Variables with the predetermined data-sharing attributes may not be 1053263508Sdim // listed in data-sharing attributes clauses, except for the cases 1054263508Sdim // listed below. For these exceptions only, listing a predetermined 1055263508Sdim // variable in a data-sharing attribute clause is allowed and overrides 1056263508Sdim // the variable's predetermined data-sharing attributes. 1057263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1058263508Sdim // in a Construct, C/C++, p.2] 1059263508Sdim // Variables with const-qualified type having no mutable member may be 1060263508Sdim // listed in a firstprivate clause, even if they are static data members. 1061263508Sdim if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr && 1062263508Sdim DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 1063263508Sdim Diag(ELoc, diag::err_omp_wrong_dsa) 1064263508Sdim << getOpenMPClauseName(DVar.CKind) 1065263508Sdim << getOpenMPClauseName(OMPC_firstprivate); 1066263508Sdim Diag(VD->getLocation(), diag::note_omp_predetermined_dsa) 1067263508Sdim << getOpenMPClauseName(DVar.CKind); 1068263508Sdim continue; 1069263508Sdim } 1070263508Sdim 1071263508Sdim // OpenMP [2.9.3.4, Restrictions, p.2] 1072263508Sdim // A list item that is private within a parallel region must not appear 1073263508Sdim // in a firstprivate clause on a worksharing construct if any of the 1074263508Sdim // worksharing regions arising from the worksharing construct ever bind 1075263508Sdim // to any of the parallel regions arising from the parallel construct. 1076263508Sdim // OpenMP [2.9.3.4, Restrictions, p.3] 1077263508Sdim // A list item that appears in a reduction clause of a parallel construct 1078263508Sdim // must not appear in a firstprivate clause on a worksharing or task 1079263508Sdim // construct if any of the worksharing or task regions arising from the 1080263508Sdim // worksharing or task construct ever bind to any of the parallel regions 1081263508Sdim // arising from the parallel construct. 1082263508Sdim // OpenMP [2.9.3.4, Restrictions, p.4] 1083263508Sdim // A list item that appears in a reduction clause in worksharing 1084263508Sdim // construct must not appear in a firstprivate clause in a task construct 1085263508Sdim // encountered during execution of any of the worksharing regions arising 1086263508Sdim // from the worksharing construct. 1087263508Sdim // TODO: 1088263508Sdim } 1089263508Sdim 1090263508Sdim DSAStack->addDSA(VD, DE, OMPC_firstprivate); 1091263508Sdim Vars.push_back(DE); 1092263508Sdim } 1093263508Sdim 1094263508Sdim if (Vars.empty()) return 0; 1095263508Sdim 1096263508Sdim return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 1097263508Sdim Vars); 1098263508Sdim} 1099263508Sdim 1100263508SdimOMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 1101263508Sdim SourceLocation StartLoc, 1102263508Sdim SourceLocation LParenLoc, 1103263508Sdim SourceLocation EndLoc) { 1104263508Sdim SmallVector<Expr *, 8> Vars; 1105263508Sdim for (ArrayRef<Expr *>::iterator I = VarList.begin(), E = VarList.end(); 1106263508Sdim I != E; ++I) { 1107263508Sdim assert(*I && "NULL expr in OpenMP shared clause."); 1108263508Sdim if (isa<DependentScopeDeclRefExpr>(*I)) { 1109263508Sdim // It will be analyzed later. 1110263508Sdim Vars.push_back(*I); 1111263508Sdim continue; 1112263508Sdim } 1113263508Sdim 1114263508Sdim SourceLocation ELoc = (*I)->getExprLoc(); 1115263508Sdim // OpenMP [2.1, C/C++] 1116263508Sdim // A list item is a variable name. 1117263508Sdim // OpenMP [2.9.3.4, Restrictions, p.1] 1118263508Sdim // A variable that is part of another variable (as an array or 1119263508Sdim // structure element) cannot appear in a private clause. 1120263508Sdim DeclRefExpr *DE = dyn_cast<DeclRefExpr>(*I); 1121263508Sdim if (!DE || !isa<VarDecl>(DE->getDecl())) { 1122263508Sdim Diag(ELoc, diag::err_omp_expected_var_name) 1123263508Sdim << (*I)->getSourceRange(); 1124263508Sdim continue; 1125263508Sdim } 1126263508Sdim Decl *D = DE->getDecl(); 1127263508Sdim VarDecl *VD = cast<VarDecl>(D); 1128263508Sdim 1129263508Sdim QualType Type = VD->getType(); 1130263508Sdim if (Type->isDependentType() || Type->isInstantiationDependentType()) { 1131263508Sdim // It will be analyzed later. 1132263508Sdim Vars.push_back(DE); 1133263508Sdim continue; 1134263508Sdim } 1135263508Sdim 1136263508Sdim // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1137263508Sdim // in a Construct] 1138263508Sdim // Variables with the predetermined data-sharing attributes may not be 1139263508Sdim // listed in data-sharing attributes clauses, except for the cases 1140263508Sdim // listed below. For these exceptions only, listing a predetermined 1141263508Sdim // variable in a data-sharing attribute clause is allowed and overrides 1142263508Sdim // the variable's predetermined data-sharing attributes. 1143263508Sdim DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD); 1144263508Sdim if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && DVar.RefExpr) { 1145263508Sdim Diag(ELoc, diag::err_omp_wrong_dsa) 1146263508Sdim << getOpenMPClauseName(DVar.CKind) 1147263508Sdim << getOpenMPClauseName(OMPC_shared); 1148263508Sdim Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1149263508Sdim << getOpenMPClauseName(DVar.CKind); 1150263508Sdim continue; 1151263508Sdim } 1152263508Sdim 1153263508Sdim DSAStack->addDSA(VD, DE, OMPC_shared); 1154263508Sdim Vars.push_back(DE); 1155263508Sdim } 1156263508Sdim 1157263508Sdim if (Vars.empty()) return 0; 1158263508Sdim 1159263508Sdim return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 1160263508Sdim} 1161263508Sdim 1162263508Sdim#undef DSAStack 1163