clang API Documentation
00001 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// \file 00010 /// \brief This file implements semantic analysis for OpenMP directives and 00011 /// clauses. 00012 /// 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/AST/ASTContext.h" 00016 #include "clang/AST/ASTMutationListener.h" 00017 #include "clang/AST/Decl.h" 00018 #include "clang/AST/DeclCXX.h" 00019 #include "clang/AST/DeclOpenMP.h" 00020 #include "clang/AST/StmtCXX.h" 00021 #include "clang/AST/StmtOpenMP.h" 00022 #include "clang/AST/StmtVisitor.h" 00023 #include "clang/Basic/OpenMPKinds.h" 00024 #include "clang/Lex/Preprocessor.h" 00025 #include "clang/Sema/Initialization.h" 00026 #include "clang/Sema/Lookup.h" 00027 #include "clang/Sema/Scope.h" 00028 #include "clang/Sema/ScopeInfo.h" 00029 #include "clang/Sema/SemaInternal.h" 00030 using namespace clang; 00031 00032 //===----------------------------------------------------------------------===// 00033 // Stack of data-sharing attributes for variables 00034 //===----------------------------------------------------------------------===// 00035 00036 namespace { 00037 /// \brief Default data sharing attributes, which can be applied to directive. 00038 enum DefaultDataSharingAttributes { 00039 DSA_unspecified = 0, /// \brief Data sharing attribute not specified. 00040 DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'. 00041 DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'. 00042 }; 00043 00044 template <class T> struct MatchesAny { 00045 explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {} 00046 bool operator()(T Kind) { 00047 for (auto KindEl : Arr) 00048 if (KindEl == Kind) 00049 return true; 00050 return false; 00051 } 00052 00053 private: 00054 ArrayRef<T> Arr; 00055 }; 00056 struct MatchesAlways { 00057 MatchesAlways() {} 00058 template <class T> bool operator()(T) { return true; } 00059 }; 00060 00061 typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause; 00062 typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective; 00063 00064 /// \brief Stack for tracking declarations used in OpenMP directives and 00065 /// clauses and their data-sharing attributes. 00066 class DSAStackTy { 00067 public: 00068 struct DSAVarData { 00069 OpenMPDirectiveKind DKind; 00070 OpenMPClauseKind CKind; 00071 DeclRefExpr *RefExpr; 00072 SourceLocation ImplicitDSALoc; 00073 DSAVarData() 00074 : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr), 00075 ImplicitDSALoc() {} 00076 }; 00077 00078 private: 00079 struct DSAInfo { 00080 OpenMPClauseKind Attributes; 00081 DeclRefExpr *RefExpr; 00082 }; 00083 typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy; 00084 typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy; 00085 00086 struct SharingMapTy { 00087 DeclSAMapTy SharingMap; 00088 AlignedMapTy AlignedMap; 00089 DefaultDataSharingAttributes DefaultAttr; 00090 SourceLocation DefaultAttrLoc; 00091 OpenMPDirectiveKind Directive; 00092 DeclarationNameInfo DirectiveName; 00093 Scope *CurScope; 00094 SourceLocation ConstructLoc; 00095 bool OrderedRegion; 00096 SourceLocation InnerTeamsRegionLoc; 00097 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 00098 Scope *CurScope, SourceLocation Loc) 00099 : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified), 00100 Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope), 00101 ConstructLoc(Loc), OrderedRegion(false), InnerTeamsRegionLoc() {} 00102 SharingMapTy() 00103 : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified), 00104 Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr), 00105 ConstructLoc(), OrderedRegion(false), InnerTeamsRegionLoc() {} 00106 }; 00107 00108 typedef SmallVector<SharingMapTy, 64> StackTy; 00109 00110 /// \brief Stack of used declaration and their data-sharing attributes. 00111 StackTy Stack; 00112 Sema &SemaRef; 00113 00114 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; 00115 00116 DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D); 00117 00118 /// \brief Checks if the variable is a local for OpenMP region. 00119 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); 00120 00121 public: 00122 explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {} 00123 00124 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 00125 Scope *CurScope, SourceLocation Loc) { 00126 Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc)); 00127 Stack.back().DefaultAttrLoc = Loc; 00128 } 00129 00130 void pop() { 00131 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!"); 00132 Stack.pop_back(); 00133 } 00134 00135 /// \brief If 'aligned' declaration for given variable \a D was not seen yet, 00136 /// add it and return NULL; otherwise return previous occurrence's expression 00137 /// for diagnostics. 00138 DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE); 00139 00140 /// \brief Adds explicit data sharing attribute to the specified declaration. 00141 void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A); 00142 00143 /// \brief Returns data sharing attributes from top of the stack for the 00144 /// specified declaration. 00145 DSAVarData getTopDSA(VarDecl *D, bool FromParent); 00146 /// \brief Returns data-sharing attributes for the specified declaration. 00147 DSAVarData getImplicitDSA(VarDecl *D, bool FromParent); 00148 /// \brief Checks if the specified variables has data-sharing attributes which 00149 /// match specified \a CPred predicate in any directive which matches \a DPred 00150 /// predicate. 00151 template <class ClausesPredicate, class DirectivesPredicate> 00152 DSAVarData hasDSA(VarDecl *D, ClausesPredicate CPred, 00153 DirectivesPredicate DPred, bool FromParent); 00154 /// \brief Checks if the specified variables has data-sharing attributes which 00155 /// match specified \a CPred predicate in any innermost directive which 00156 /// matches \a DPred predicate. 00157 template <class ClausesPredicate, class DirectivesPredicate> 00158 DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, 00159 DirectivesPredicate DPred, 00160 bool FromParent); 00161 /// \brief Finds a directive which matches specified \a DPred predicate. 00162 template <class NamedDirectivesPredicate> 00163 bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent); 00164 00165 /// \brief Returns currently analyzed directive. 00166 OpenMPDirectiveKind getCurrentDirective() const { 00167 return Stack.back().Directive; 00168 } 00169 /// \brief Returns parent directive. 00170 OpenMPDirectiveKind getParentDirective() const { 00171 if (Stack.size() > 2) 00172 return Stack[Stack.size() - 2].Directive; 00173 return OMPD_unknown; 00174 } 00175 00176 /// \brief Set default data sharing attribute to none. 00177 void setDefaultDSANone(SourceLocation Loc) { 00178 Stack.back().DefaultAttr = DSA_none; 00179 Stack.back().DefaultAttrLoc = Loc; 00180 } 00181 /// \brief Set default data sharing attribute to shared. 00182 void setDefaultDSAShared(SourceLocation Loc) { 00183 Stack.back().DefaultAttr = DSA_shared; 00184 Stack.back().DefaultAttrLoc = Loc; 00185 } 00186 00187 DefaultDataSharingAttributes getDefaultDSA() const { 00188 return Stack.back().DefaultAttr; 00189 } 00190 SourceLocation getDefaultDSALocation() const { 00191 return Stack.back().DefaultAttrLoc; 00192 } 00193 00194 /// \brief Checks if the specified variable is a threadprivate. 00195 bool isThreadPrivate(VarDecl *D) { 00196 DSAVarData DVar = getTopDSA(D, false); 00197 return isOpenMPThreadPrivate(DVar.CKind); 00198 } 00199 00200 /// \brief Marks current region as ordered (it has an 'ordered' clause). 00201 void setOrderedRegion(bool IsOrdered = true) { 00202 Stack.back().OrderedRegion = IsOrdered; 00203 } 00204 /// \brief Returns true, if parent region is ordered (has associated 00205 /// 'ordered' clause), false - otherwise. 00206 bool isParentOrderedRegion() const { 00207 if (Stack.size() > 2) 00208 return Stack[Stack.size() - 2].OrderedRegion; 00209 return false; 00210 } 00211 00212 /// \brief Marks current target region as one with closely nested teams 00213 /// region. 00214 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 00215 if (Stack.size() > 2) 00216 Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc; 00217 } 00218 /// \brief Returns true, if current region has closely nested teams region. 00219 bool hasInnerTeamsRegion() const { 00220 return getInnerTeamsRegionLoc().isValid(); 00221 } 00222 /// \brief Returns location of the nested teams region (if any). 00223 SourceLocation getInnerTeamsRegionLoc() const { 00224 if (Stack.size() > 1) 00225 return Stack.back().InnerTeamsRegionLoc; 00226 return SourceLocation(); 00227 } 00228 00229 Scope *getCurScope() const { return Stack.back().CurScope; } 00230 Scope *getCurScope() { return Stack.back().CurScope; } 00231 SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } 00232 }; 00233 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 00234 return isOpenMPParallelDirective(DKind) || DKind == OMPD_task || 00235 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 00236 } 00237 } // namespace 00238 00239 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter, 00240 VarDecl *D) { 00241 DSAVarData DVar; 00242 if (Iter == std::prev(Stack.rend())) { 00243 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 00244 // in a region but not in construct] 00245 // File-scope or namespace-scope variables referenced in called routines 00246 // in the region are shared unless they appear in a threadprivate 00247 // directive. 00248 if (!D->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) 00249 DVar.CKind = OMPC_shared; 00250 00251 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 00252 // in a region but not in construct] 00253 // Variables with static storage duration that are declared in called 00254 // routines in the region are shared. 00255 if (D->hasGlobalStorage()) 00256 DVar.CKind = OMPC_shared; 00257 00258 return DVar; 00259 } 00260 00261 DVar.DKind = Iter->Directive; 00262 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 00263 // in a Construct, C/C++, predetermined, p.1] 00264 // Variables with automatic storage duration that are declared in a scope 00265 // inside the construct are private. 00266 if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() && 00267 (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) { 00268 DVar.CKind = OMPC_private; 00269 return DVar; 00270 } 00271 00272 // Explicitly specified attributes and local variables with predetermined 00273 // attributes. 00274 if (Iter->SharingMap.count(D)) { 00275 DVar.RefExpr = Iter->SharingMap[D].RefExpr; 00276 DVar.CKind = Iter->SharingMap[D].Attributes; 00277 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 00278 return DVar; 00279 } 00280 00281 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 00282 // in a Construct, C/C++, implicitly determined, p.1] 00283 // In a parallel or task construct, the data-sharing attributes of these 00284 // variables are determined by the default clause, if present. 00285 switch (Iter->DefaultAttr) { 00286 case DSA_shared: 00287 DVar.CKind = OMPC_shared; 00288 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 00289 return DVar; 00290 case DSA_none: 00291 return DVar; 00292 case DSA_unspecified: 00293 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 00294 // in a Construct, implicitly determined, p.2] 00295 // In a parallel construct, if no default clause is present, these 00296 // variables are shared. 00297 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 00298 if (isOpenMPParallelDirective(DVar.DKind) || 00299 isOpenMPTeamsDirective(DVar.DKind)) { 00300 DVar.CKind = OMPC_shared; 00301 return DVar; 00302 } 00303 00304 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 00305 // in a Construct, implicitly determined, p.4] 00306 // In a task construct, if no default clause is present, a variable that in 00307 // the enclosing context is determined to be shared by all implicit tasks 00308 // bound to the current team is shared. 00309 if (DVar.DKind == OMPD_task) { 00310 DSAVarData DVarTemp; 00311 for (StackTy::reverse_iterator I = std::next(Iter), 00312 EE = std::prev(Stack.rend()); 00313 I != EE; ++I) { 00314 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 00315 // Referenced 00316 // in a Construct, implicitly determined, p.6] 00317 // In a task construct, if no default clause is present, a variable 00318 // whose data-sharing attribute is not determined by the rules above is 00319 // firstprivate. 00320 DVarTemp = getDSA(I, D); 00321 if (DVarTemp.CKind != OMPC_shared) { 00322 DVar.RefExpr = nullptr; 00323 DVar.DKind = OMPD_task; 00324 DVar.CKind = OMPC_firstprivate; 00325 return DVar; 00326 } 00327 if (isParallelOrTaskRegion(I->Directive)) 00328 break; 00329 } 00330 DVar.DKind = OMPD_task; 00331 DVar.CKind = 00332 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 00333 return DVar; 00334 } 00335 } 00336 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 00337 // in a Construct, implicitly determined, p.3] 00338 // For constructs other than task, if no default clause is present, these 00339 // variables inherit their data-sharing attributes from the enclosing 00340 // context. 00341 return getDSA(std::next(Iter), D); 00342 } 00343 00344 DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) { 00345 assert(Stack.size() > 1 && "Data sharing attributes stack is empty"); 00346 auto It = Stack.back().AlignedMap.find(D); 00347 if (It == Stack.back().AlignedMap.end()) { 00348 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 00349 Stack.back().AlignedMap[D] = NewDE; 00350 return nullptr; 00351 } else { 00352 assert(It->second && "Unexpected nullptr expr in the aligned map"); 00353 return It->second; 00354 } 00355 return nullptr; 00356 } 00357 00358 void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) { 00359 if (A == OMPC_threadprivate) { 00360 Stack[0].SharingMap[D].Attributes = A; 00361 Stack[0].SharingMap[D].RefExpr = E; 00362 } else { 00363 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 00364 Stack.back().SharingMap[D].Attributes = A; 00365 Stack.back().SharingMap[D].RefExpr = E; 00366 } 00367 } 00368 00369 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { 00370 if (Stack.size() > 2) { 00371 reverse_iterator I = Iter, E = std::prev(Stack.rend()); 00372 Scope *TopScope = nullptr; 00373 while (I != E && !isParallelOrTaskRegion(I->Directive)) { 00374 ++I; 00375 } 00376 if (I == E) 00377 return false; 00378 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 00379 Scope *CurScope = getCurScope(); 00380 while (CurScope != TopScope && !CurScope->isDeclScope(D)) { 00381 CurScope = CurScope->getParent(); 00382 } 00383 return CurScope != TopScope; 00384 } 00385 return false; 00386 } 00387 00388 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) { 00389 DSAVarData DVar; 00390 00391 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 00392 // in a Construct, C/C++, predetermined, p.1] 00393 // Variables appearing in threadprivate directives are threadprivate. 00394 if (D->getTLSKind() != VarDecl::TLS_None) { 00395 DVar.CKind = OMPC_threadprivate; 00396 return DVar; 00397 } 00398 if (Stack[0].SharingMap.count(D)) { 00399 DVar.RefExpr = Stack[0].SharingMap[D].RefExpr; 00400 DVar.CKind = OMPC_threadprivate; 00401 return DVar; 00402 } 00403 00404 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 00405 // in a Construct, C/C++, predetermined, p.1] 00406 // Variables with automatic storage duration that are declared in a scope 00407 // inside the construct are private. 00408 OpenMPDirectiveKind Kind = 00409 FromParent ? getParentDirective() : getCurrentDirective(); 00410 auto StartI = std::next(Stack.rbegin()); 00411 auto EndI = std::prev(Stack.rend()); 00412 if (FromParent && StartI != EndI) { 00413 StartI = std::next(StartI); 00414 } 00415 if (!isParallelOrTaskRegion(Kind)) { 00416 if (isOpenMPLocal(D, StartI) && 00417 ((D->isLocalVarDecl() && (D->getStorageClass() == SC_Auto || 00418 D->getStorageClass() == SC_None)) || 00419 isa<ParmVarDecl>(D))) { 00420 DVar.CKind = OMPC_private; 00421 return DVar; 00422 } 00423 } 00424 00425 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 00426 // in a Construct, C/C++, predetermined, p.4] 00427 // Static data members are shared. 00428 if (D->isStaticDataMember()) { 00429 // Variables with const-qualified type having no mutable member may be 00430 // listed in a firstprivate clause, even if they are static data members. 00431 DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate), 00432 MatchesAlways(), FromParent); 00433 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 00434 return DVar; 00435 00436 DVar.CKind = OMPC_shared; 00437 return DVar; 00438 } 00439 00440 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 00441 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 00442 while (Type->isArrayType()) { 00443 QualType ElemType = cast<ArrayType>(Type.getTypePtr())->getElementType(); 00444 Type = ElemType.getNonReferenceType().getCanonicalType(); 00445 } 00446 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 00447 // in a Construct, C/C++, predetermined, p.6] 00448 // Variables with const qualified type having no mutable member are 00449 // shared. 00450 CXXRecordDecl *RD = 00451 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 00452 if (IsConstant && 00453 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) { 00454 // Variables with const-qualified type having no mutable member may be 00455 // listed in a firstprivate clause, even if they are static data members. 00456 DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate), 00457 MatchesAlways(), FromParent); 00458 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 00459 return DVar; 00460 00461 DVar.CKind = OMPC_shared; 00462 return DVar; 00463 } 00464 00465 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 00466 // in a Construct, C/C++, predetermined, p.7] 00467 // Variables with static storage duration that are declared in a scope 00468 // inside the construct are shared. 00469 if (D->isStaticLocal()) { 00470 DVar.CKind = OMPC_shared; 00471 return DVar; 00472 } 00473 00474 // Explicitly specified attributes and local variables with predetermined 00475 // attributes. 00476 auto I = std::prev(StartI); 00477 if (I->SharingMap.count(D)) { 00478 DVar.RefExpr = I->SharingMap[D].RefExpr; 00479 DVar.CKind = I->SharingMap[D].Attributes; 00480 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 00481 } 00482 00483 return DVar; 00484 } 00485 00486 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D, bool FromParent) { 00487 auto StartI = Stack.rbegin(); 00488 auto EndI = std::prev(Stack.rend()); 00489 if (FromParent && StartI != EndI) { 00490 StartI = std::next(StartI); 00491 } 00492 return getDSA(StartI, D); 00493 } 00494 00495 template <class ClausesPredicate, class DirectivesPredicate> 00496 DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, ClausesPredicate CPred, 00497 DirectivesPredicate DPred, 00498 bool FromParent) { 00499 auto StartI = std::next(Stack.rbegin()); 00500 auto EndI = std::prev(Stack.rend()); 00501 if (FromParent && StartI != EndI) { 00502 StartI = std::next(StartI); 00503 } 00504 for (auto I = StartI, EE = EndI; I != EE; ++I) { 00505 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 00506 continue; 00507 DSAVarData DVar = getDSA(I, D); 00508 if (CPred(DVar.CKind)) 00509 return DVar; 00510 } 00511 return DSAVarData(); 00512 } 00513 00514 template <class ClausesPredicate, class DirectivesPredicate> 00515 DSAStackTy::DSAVarData 00516 DSAStackTy::hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, 00517 DirectivesPredicate DPred, bool FromParent) { 00518 auto StartI = std::next(Stack.rbegin()); 00519 auto EndI = std::prev(Stack.rend()); 00520 if (FromParent && StartI != EndI) { 00521 StartI = std::next(StartI); 00522 } 00523 for (auto I = StartI, EE = EndI; I != EE; ++I) { 00524 if (!DPred(I->Directive)) 00525 break; 00526 DSAVarData DVar = getDSA(I, D); 00527 if (CPred(DVar.CKind)) 00528 return DVar; 00529 return DSAVarData(); 00530 } 00531 return DSAVarData(); 00532 } 00533 00534 template <class NamedDirectivesPredicate> 00535 bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) { 00536 auto StartI = std::next(Stack.rbegin()); 00537 auto EndI = std::prev(Stack.rend()); 00538 if (FromParent && StartI != EndI) { 00539 StartI = std::next(StartI); 00540 } 00541 for (auto I = StartI, EE = EndI; I != EE; ++I) { 00542 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 00543 return true; 00544 } 00545 return false; 00546 } 00547 00548 void Sema::InitDataSharingAttributesStack() { 00549 VarDataSharingAttributesStack = new DSAStackTy(*this); 00550 } 00551 00552 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 00553 00554 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 00555 00556 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 00557 const DeclarationNameInfo &DirName, 00558 Scope *CurScope, SourceLocation Loc) { 00559 DSAStack->push(DKind, DirName, CurScope, Loc); 00560 PushExpressionEvaluationContext(PotentiallyEvaluated); 00561 } 00562 00563 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 00564 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 00565 // A variable of class type (or array thereof) that appears in a lastprivate 00566 // clause requires an accessible, unambiguous default constructor for the 00567 // class type, unless the list item is also specified in a firstprivate 00568 // clause. 00569 if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 00570 for (auto C : D->clauses()) { 00571 if (auto Clause = dyn_cast<OMPLastprivateClause>(C)) { 00572 for (auto VarRef : Clause->varlists()) { 00573 if (VarRef->isValueDependent() || VarRef->isTypeDependent()) 00574 continue; 00575 auto VD = cast<VarDecl>(cast<DeclRefExpr>(VarRef)->getDecl()); 00576 auto DVar = DSAStack->getTopDSA(VD, false); 00577 if (DVar.CKind == OMPC_lastprivate) { 00578 SourceLocation ELoc = VarRef->getExprLoc(); 00579 auto Type = VarRef->getType(); 00580 if (Type->isArrayType()) 00581 Type = QualType(Type->getArrayElementTypeNoTypeQual(), 0); 00582 CXXRecordDecl *RD = 00583 getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 00584 // FIXME This code must be replaced by actual constructing of the 00585 // lastprivate variable. 00586 if (RD) { 00587 CXXConstructorDecl *CD = LookupDefaultConstructor(RD); 00588 PartialDiagnostic PD = 00589 PartialDiagnostic(PartialDiagnostic::NullDiagnostic()); 00590 if (!CD || 00591 CheckConstructorAccess( 00592 ELoc, CD, InitializedEntity::InitializeTemporary(Type), 00593 CD->getAccess(), PD) == AR_inaccessible || 00594 CD->isDeleted()) { 00595 Diag(ELoc, diag::err_omp_required_method) 00596 << getOpenMPClauseName(OMPC_lastprivate) << 0; 00597 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 00598 VarDecl::DeclarationOnly; 00599 Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl 00600 : diag::note_defined_here) 00601 << VD; 00602 Diag(RD->getLocation(), diag::note_previous_decl) << RD; 00603 continue; 00604 } 00605 MarkFunctionReferenced(ELoc, CD); 00606 DiagnoseUseOfDecl(CD, ELoc); 00607 } 00608 } 00609 } 00610 } 00611 } 00612 } 00613 00614 DSAStack->pop(); 00615 DiscardCleanupsInEvaluationContext(); 00616 PopExpressionEvaluationContext(); 00617 } 00618 00619 namespace { 00620 00621 class VarDeclFilterCCC : public CorrectionCandidateCallback { 00622 private: 00623 Sema &SemaRef; 00624 00625 public: 00626 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 00627 bool ValidateCandidate(const TypoCorrection &Candidate) override { 00628 NamedDecl *ND = Candidate.getCorrectionDecl(); 00629 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) { 00630 return VD->hasGlobalStorage() && 00631 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 00632 SemaRef.getCurScope()); 00633 } 00634 return false; 00635 } 00636 }; 00637 } // namespace 00638 00639 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 00640 CXXScopeSpec &ScopeSpec, 00641 const DeclarationNameInfo &Id) { 00642 LookupResult Lookup(*this, Id, LookupOrdinaryName); 00643 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 00644 00645 if (Lookup.isAmbiguous()) 00646 return ExprError(); 00647 00648 VarDecl *VD; 00649 if (!Lookup.isSingleResult()) { 00650 if (TypoCorrection Corrected = CorrectTypo( 00651 Id, LookupOrdinaryName, CurScope, nullptr, 00652 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 00653 diagnoseTypo(Corrected, 00654 PDiag(Lookup.empty() 00655 ? diag::err_undeclared_var_use_suggest 00656 : diag::err_omp_expected_var_arg_suggest) 00657 << Id.getName()); 00658 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 00659 } else { 00660 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 00661 : diag::err_omp_expected_var_arg) 00662 << Id.getName(); 00663 return ExprError(); 00664 } 00665 } else { 00666 if (!(VD = Lookup.getAsSingle<VarDecl>())) { 00667 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 00668 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 00669 return ExprError(); 00670 } 00671 } 00672 Lookup.suppressDiagnostics(); 00673 00674 // OpenMP [2.9.2, Syntax, C/C++] 00675 // Variables must be file-scope, namespace-scope, or static block-scope. 00676 if (!VD->hasGlobalStorage()) { 00677 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 00678 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 00679 bool IsDecl = 00680 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 00681 Diag(VD->getLocation(), 00682 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 00683 << VD; 00684 return ExprError(); 00685 } 00686 00687 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 00688 NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 00689 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 00690 // A threadprivate directive for file-scope variables must appear outside 00691 // any definition or declaration. 00692 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 00693 !getCurLexicalContext()->isTranslationUnit()) { 00694 Diag(Id.getLoc(), diag::err_omp_var_scope) 00695 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 00696 bool IsDecl = 00697 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 00698 Diag(VD->getLocation(), 00699 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 00700 << VD; 00701 return ExprError(); 00702 } 00703 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 00704 // A threadprivate directive for static class member variables must appear 00705 // in the class definition, in the same scope in which the member 00706 // variables are declared. 00707 if (CanonicalVD->isStaticDataMember() && 00708 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 00709 Diag(Id.getLoc(), diag::err_omp_var_scope) 00710 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 00711 bool IsDecl = 00712 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 00713 Diag(VD->getLocation(), 00714 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 00715 << VD; 00716 return ExprError(); 00717 } 00718 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 00719 // A threadprivate directive for namespace-scope variables must appear 00720 // outside any definition or declaration other than the namespace 00721 // definition itself. 00722 if (CanonicalVD->getDeclContext()->isNamespace() && 00723 (!getCurLexicalContext()->isFileContext() || 00724 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 00725 Diag(Id.getLoc(), diag::err_omp_var_scope) 00726 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 00727 bool IsDecl = 00728 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 00729 Diag(VD->getLocation(), 00730 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 00731 << VD; 00732 return ExprError(); 00733 } 00734 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 00735 // A threadprivate directive for static block-scope variables must appear 00736 // in the scope of the variable and not in a nested scope. 00737 if (CanonicalVD->isStaticLocal() && CurScope && 00738 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 00739 Diag(Id.getLoc(), diag::err_omp_var_scope) 00740 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 00741 bool IsDecl = 00742 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 00743 Diag(VD->getLocation(), 00744 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 00745 << VD; 00746 return ExprError(); 00747 } 00748 00749 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 00750 // A threadprivate directive must lexically precede all references to any 00751 // of the variables in its list. 00752 if (VD->isUsed()) { 00753 Diag(Id.getLoc(), diag::err_omp_var_used) 00754 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 00755 return ExprError(); 00756 } 00757 00758 QualType ExprType = VD->getType().getNonReferenceType(); 00759 ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_LValue, Id.getLoc()); 00760 return DE; 00761 } 00762 00763 Sema::DeclGroupPtrTy 00764 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 00765 ArrayRef<Expr *> VarList) { 00766 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 00767 CurContext->addDecl(D); 00768 return DeclGroupPtrTy::make(DeclGroupRef(D)); 00769 } 00770 return DeclGroupPtrTy(); 00771 } 00772 00773 namespace { 00774 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { 00775 Sema &SemaRef; 00776 00777 public: 00778 bool VisitDeclRefExpr(const DeclRefExpr *E) { 00779 if (auto VD = dyn_cast<VarDecl>(E->getDecl())) { 00780 if (VD->hasLocalStorage()) { 00781 SemaRef.Diag(E->getLocStart(), 00782 diag::err_omp_local_var_in_threadprivate_init) 00783 << E->getSourceRange(); 00784 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 00785 << VD << VD->getSourceRange(); 00786 return true; 00787 } 00788 } 00789 return false; 00790 } 00791 bool VisitStmt(const Stmt *S) { 00792 for (auto Child : S->children()) { 00793 if (Child && Visit(Child)) 00794 return true; 00795 } 00796 return false; 00797 } 00798 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 00799 }; 00800 } // namespace 00801 00802 OMPThreadPrivateDecl * 00803 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 00804 SmallVector<Expr *, 8> Vars; 00805 for (auto &RefExpr : VarList) { 00806 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); 00807 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 00808 SourceLocation ILoc = DE->getExprLoc(); 00809 00810 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 00811 // A threadprivate variable must not have an incomplete type. 00812 if (RequireCompleteType(ILoc, VD->getType(), 00813 diag::err_omp_threadprivate_incomplete_type)) { 00814 continue; 00815 } 00816 00817 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 00818 // A threadprivate variable must not have a reference type. 00819 if (VD->getType()->isReferenceType()) { 00820 Diag(ILoc, diag::err_omp_ref_type_arg) 00821 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 00822 bool IsDecl = 00823 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 00824 Diag(VD->getLocation(), 00825 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 00826 << VD; 00827 continue; 00828 } 00829 00830 // Check if this is a TLS variable. 00831 if (VD->getTLSKind()) { 00832 Diag(ILoc, diag::err_omp_var_thread_local) << VD; 00833 bool IsDecl = 00834 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 00835 Diag(VD->getLocation(), 00836 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 00837 << VD; 00838 continue; 00839 } 00840 00841 // Check if initial value of threadprivate variable reference variable with 00842 // local storage (it is not supported by runtime). 00843 if (auto Init = VD->getAnyInitializer()) { 00844 LocalVarRefChecker Checker(*this); 00845 if (Checker.Visit(Init)) 00846 continue; 00847 } 00848 00849 Vars.push_back(RefExpr); 00850 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 00851 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 00852 Context, SourceRange(Loc, Loc))); 00853 if (auto *ML = Context.getASTMutationListener()) 00854 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 00855 } 00856 OMPThreadPrivateDecl *D = nullptr; 00857 if (!Vars.empty()) { 00858 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 00859 Vars); 00860 D->setAccess(AS_public); 00861 } 00862 return D; 00863 } 00864 00865 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, 00866 const VarDecl *VD, DSAStackTy::DSAVarData DVar, 00867 bool IsLoopIterVar = false) { 00868 if (DVar.RefExpr) { 00869 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 00870 << getOpenMPClauseName(DVar.CKind); 00871 return; 00872 } 00873 enum { 00874 PDSA_StaticMemberShared, 00875 PDSA_StaticLocalVarShared, 00876 PDSA_LoopIterVarPrivate, 00877 PDSA_LoopIterVarLinear, 00878 PDSA_LoopIterVarLastprivate, 00879 PDSA_ConstVarShared, 00880 PDSA_GlobalVarShared, 00881 PDSA_TaskVarFirstprivate, 00882 PDSA_LocalVarPrivate, 00883 PDSA_Implicit 00884 } Reason = PDSA_Implicit; 00885 bool ReportHint = false; 00886 auto ReportLoc = VD->getLocation(); 00887 if (IsLoopIterVar) { 00888 if (DVar.CKind == OMPC_private) 00889 Reason = PDSA_LoopIterVarPrivate; 00890 else if (DVar.CKind == OMPC_lastprivate) 00891 Reason = PDSA_LoopIterVarLastprivate; 00892 else 00893 Reason = PDSA_LoopIterVarLinear; 00894 } else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) { 00895 Reason = PDSA_TaskVarFirstprivate; 00896 ReportLoc = DVar.ImplicitDSALoc; 00897 } else if (VD->isStaticLocal()) 00898 Reason = PDSA_StaticLocalVarShared; 00899 else if (VD->isStaticDataMember()) 00900 Reason = PDSA_StaticMemberShared; 00901 else if (VD->isFileVarDecl()) 00902 Reason = PDSA_GlobalVarShared; 00903 else if (VD->getType().isConstant(SemaRef.getASTContext())) 00904 Reason = PDSA_ConstVarShared; 00905 else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 00906 ReportHint = true; 00907 Reason = PDSA_LocalVarPrivate; 00908 } 00909 if (Reason != PDSA_Implicit) { 00910 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 00911 << Reason << ReportHint 00912 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 00913 } else if (DVar.ImplicitDSALoc.isValid()) { 00914 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 00915 << getOpenMPClauseName(DVar.CKind); 00916 } 00917 } 00918 00919 namespace { 00920 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 00921 DSAStackTy *Stack; 00922 Sema &SemaRef; 00923 bool ErrorFound; 00924 CapturedStmt *CS; 00925 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 00926 llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA; 00927 00928 public: 00929 void VisitDeclRefExpr(DeclRefExpr *E) { 00930 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 00931 // Skip internally declared variables. 00932 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) 00933 return; 00934 00935 auto DVar = Stack->getTopDSA(VD, false); 00936 // Check if the variable has explicit DSA set and stop analysis if it so. 00937 if (DVar.RefExpr) return; 00938 00939 auto ELoc = E->getExprLoc(); 00940 auto DKind = Stack->getCurrentDirective(); 00941 // The default(none) clause requires that each variable that is referenced 00942 // in the construct, and does not have a predetermined data-sharing 00943 // attribute, must have its data-sharing attribute explicitly determined 00944 // by being listed in a data-sharing attribute clause. 00945 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 00946 isParallelOrTaskRegion(DKind) && 00947 VarsWithInheritedDSA.count(VD) == 0) { 00948 VarsWithInheritedDSA[VD] = E; 00949 return; 00950 } 00951 00952 // OpenMP [2.9.3.6, Restrictions, p.2] 00953 // A list item that appears in a reduction clause of the innermost 00954 // enclosing worksharing or parallel construct may not be accessed in an 00955 // explicit task. 00956 DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction), 00957 [](OpenMPDirectiveKind K) -> bool { 00958 return isOpenMPParallelDirective(K) || 00959 isOpenMPWorksharingDirective(K) || 00960 isOpenMPTeamsDirective(K); 00961 }, 00962 false); 00963 if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) { 00964 ErrorFound = true; 00965 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 00966 ReportOriginalDSA(SemaRef, Stack, VD, DVar); 00967 return; 00968 } 00969 00970 // Define implicit data-sharing attributes for task. 00971 DVar = Stack->getImplicitDSA(VD, false); 00972 if (DKind == OMPD_task && DVar.CKind != OMPC_shared) 00973 ImplicitFirstprivate.push_back(E); 00974 } 00975 } 00976 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 00977 for (auto *C : S->clauses()) { 00978 // Skip analysis of arguments of implicitly defined firstprivate clause 00979 // for task directives. 00980 if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid())) 00981 for (auto *CC : C->children()) { 00982 if (CC) 00983 Visit(CC); 00984 } 00985 } 00986 } 00987 void VisitStmt(Stmt *S) { 00988 for (auto *C : S->children()) { 00989 if (C && !isa<OMPExecutableDirective>(C)) 00990 Visit(C); 00991 } 00992 } 00993 00994 bool isErrorFound() { return ErrorFound; } 00995 ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; } 00996 llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() { 00997 return VarsWithInheritedDSA; 00998 } 00999 01000 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 01001 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 01002 }; 01003 } // namespace 01004 01005 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 01006 switch (DKind) { 01007 case OMPD_parallel: { 01008 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 01009 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 01010 Sema::CapturedParamNameType Params[] = { 01011 std::make_pair(".global_tid.", KmpInt32PtrTy), 01012 std::make_pair(".bound_tid.", KmpInt32PtrTy), 01013 std::make_pair(StringRef(), QualType()) // __context with shared vars 01014 }; 01015 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01016 Params); 01017 break; 01018 } 01019 case OMPD_simd: { 01020 Sema::CapturedParamNameType Params[] = { 01021 std::make_pair(StringRef(), QualType()) // __context with shared vars 01022 }; 01023 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01024 Params); 01025 break; 01026 } 01027 case OMPD_for: { 01028 Sema::CapturedParamNameType Params[] = { 01029 std::make_pair(StringRef(), QualType()) // __context with shared vars 01030 }; 01031 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01032 Params); 01033 break; 01034 } 01035 case OMPD_for_simd: { 01036 Sema::CapturedParamNameType Params[] = { 01037 std::make_pair(StringRef(), QualType()) // __context with shared vars 01038 }; 01039 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01040 Params); 01041 break; 01042 } 01043 case OMPD_sections: { 01044 Sema::CapturedParamNameType Params[] = { 01045 std::make_pair(StringRef(), QualType()) // __context with shared vars 01046 }; 01047 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01048 Params); 01049 break; 01050 } 01051 case OMPD_section: { 01052 Sema::CapturedParamNameType Params[] = { 01053 std::make_pair(StringRef(), QualType()) // __context with shared vars 01054 }; 01055 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01056 Params); 01057 break; 01058 } 01059 case OMPD_single: { 01060 Sema::CapturedParamNameType Params[] = { 01061 std::make_pair(StringRef(), QualType()) // __context with shared vars 01062 }; 01063 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01064 Params); 01065 break; 01066 } 01067 case OMPD_master: { 01068 Sema::CapturedParamNameType Params[] = { 01069 std::make_pair(StringRef(), QualType()) // __context with shared vars 01070 }; 01071 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01072 Params); 01073 break; 01074 } 01075 case OMPD_critical: { 01076 Sema::CapturedParamNameType Params[] = { 01077 std::make_pair(StringRef(), QualType()) // __context with shared vars 01078 }; 01079 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01080 Params); 01081 break; 01082 } 01083 case OMPD_parallel_for: { 01084 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 01085 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 01086 Sema::CapturedParamNameType Params[] = { 01087 std::make_pair(".global_tid.", KmpInt32PtrTy), 01088 std::make_pair(".bound_tid.", KmpInt32PtrTy), 01089 std::make_pair(StringRef(), QualType()) // __context with shared vars 01090 }; 01091 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01092 Params); 01093 break; 01094 } 01095 case OMPD_parallel_for_simd: { 01096 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 01097 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 01098 Sema::CapturedParamNameType Params[] = { 01099 std::make_pair(".global_tid.", KmpInt32PtrTy), 01100 std::make_pair(".bound_tid.", KmpInt32PtrTy), 01101 std::make_pair(StringRef(), QualType()) // __context with shared vars 01102 }; 01103 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01104 Params); 01105 break; 01106 } 01107 case OMPD_parallel_sections: { 01108 Sema::CapturedParamNameType Params[] = { 01109 std::make_pair(StringRef(), QualType()) // __context with shared vars 01110 }; 01111 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01112 Params); 01113 break; 01114 } 01115 case OMPD_task: { 01116 Sema::CapturedParamNameType Params[] = { 01117 std::make_pair(StringRef(), QualType()) // __context with shared vars 01118 }; 01119 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01120 Params); 01121 break; 01122 } 01123 case OMPD_taskyield: { 01124 Sema::CapturedParamNameType Params[] = { 01125 std::make_pair(StringRef(), QualType()) // __context with shared vars 01126 }; 01127 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01128 Params); 01129 break; 01130 } 01131 case OMPD_barrier: { 01132 Sema::CapturedParamNameType Params[] = { 01133 std::make_pair(StringRef(), QualType()) // __context with shared vars 01134 }; 01135 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01136 Params); 01137 break; 01138 } 01139 case OMPD_taskwait: { 01140 Sema::CapturedParamNameType Params[] = { 01141 std::make_pair(StringRef(), QualType()) // __context with shared vars 01142 }; 01143 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01144 Params); 01145 break; 01146 } 01147 case OMPD_flush: { 01148 Sema::CapturedParamNameType Params[] = { 01149 std::make_pair(StringRef(), QualType()) // __context with shared vars 01150 }; 01151 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01152 Params); 01153 break; 01154 } 01155 case OMPD_ordered: { 01156 Sema::CapturedParamNameType Params[] = { 01157 std::make_pair(StringRef(), QualType()) // __context with shared vars 01158 }; 01159 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01160 Params); 01161 break; 01162 } 01163 case OMPD_atomic: { 01164 Sema::CapturedParamNameType Params[] = { 01165 std::make_pair(StringRef(), QualType()) // __context with shared vars 01166 }; 01167 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01168 Params); 01169 break; 01170 } 01171 case OMPD_target: { 01172 Sema::CapturedParamNameType Params[] = { 01173 std::make_pair(StringRef(), QualType()) // __context with shared vars 01174 }; 01175 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01176 Params); 01177 break; 01178 } 01179 case OMPD_teams: { 01180 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 01181 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 01182 Sema::CapturedParamNameType Params[] = { 01183 std::make_pair(".global_tid.", KmpInt32PtrTy), 01184 std::make_pair(".bound_tid.", KmpInt32PtrTy), 01185 std::make_pair(StringRef(), QualType()) // __context with shared vars 01186 }; 01187 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 01188 Params); 01189 break; 01190 } 01191 case OMPD_threadprivate: 01192 llvm_unreachable("OpenMP Directive is not allowed"); 01193 case OMPD_unknown: 01194 llvm_unreachable("Unknown OpenMP directive"); 01195 } 01196 } 01197 01198 static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, 01199 OpenMPDirectiveKind CurrentRegion, 01200 const DeclarationNameInfo &CurrentName, 01201 SourceLocation StartLoc) { 01202 // Allowed nesting of constructs 01203 // +------------------+-----------------+------------------------------------+ 01204 // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)| 01205 // +------------------+-----------------+------------------------------------+ 01206 // | parallel | parallel | * | 01207 // | parallel | for | * | 01208 // | parallel | for simd | * | 01209 // | parallel | master | * | 01210 // | parallel | critical | * | 01211 // | parallel | simd | * | 01212 // | parallel | sections | * | 01213 // | parallel | section | + | 01214 // | parallel | single | * | 01215 // | parallel | parallel for | * | 01216 // | parallel |parallel for simd| * | 01217 // | parallel |parallel sections| * | 01218 // | parallel | task | * | 01219 // | parallel | taskyield | * | 01220 // | parallel | barrier | * | 01221 // | parallel | taskwait | * | 01222 // | parallel | flush | * | 01223 // | parallel | ordered | + | 01224 // | parallel | atomic | * | 01225 // | parallel | target | * | 01226 // | parallel | teams | + | 01227 // +------------------+-----------------+------------------------------------+ 01228 // | for | parallel | * | 01229 // | for | for | + | 01230 // | for | for simd | + | 01231 // | for | master | + | 01232 // | for | critical | * | 01233 // | for | simd | * | 01234 // | for | sections | + | 01235 // | for | section | + | 01236 // | for | single | + | 01237 // | for | parallel for | * | 01238 // | for |parallel for simd| * | 01239 // | for |parallel sections| * | 01240 // | for | task | * | 01241 // | for | taskyield | * | 01242 // | for | barrier | + | 01243 // | for | taskwait | * | 01244 // | for | flush | * | 01245 // | for | ordered | * (if construct is ordered) | 01246 // | for | atomic | * | 01247 // | for | target | * | 01248 // | for | teams | + | 01249 // +------------------+-----------------+------------------------------------+ 01250 // | master | parallel | * | 01251 // | master | for | + | 01252 // | master | for simd | + | 01253 // | master | master | * | 01254 // | master | critical | * | 01255 // | master | simd | * | 01256 // | master | sections | + | 01257 // | master | section | + | 01258 // | master | single | + | 01259 // | master | parallel for | * | 01260 // | master |parallel for simd| * | 01261 // | master |parallel sections| * | 01262 // | master | task | * | 01263 // | master | taskyield | * | 01264 // | master | barrier | + | 01265 // | master | taskwait | * | 01266 // | master | flush | * | 01267 // | master | ordered | + | 01268 // | master | atomic | * | 01269 // | master | target | * | 01270 // | master | teams | + | 01271 // +------------------+-----------------+------------------------------------+ 01272 // | critical | parallel | * | 01273 // | critical | for | + | 01274 // | critical | for simd | + | 01275 // | critical | master | * | 01276 // | critical | critical | * (should have different names) | 01277 // | critical | simd | * | 01278 // | critical | sections | + | 01279 // | critical | section | + | 01280 // | critical | single | + | 01281 // | critical | parallel for | * | 01282 // | critical |parallel for simd| * | 01283 // | critical |parallel sections| * | 01284 // | critical | task | * | 01285 // | critical | taskyield | * | 01286 // | critical | barrier | + | 01287 // | critical | taskwait | * | 01288 // | critical | ordered | + | 01289 // | critical | atomic | * | 01290 // | critical | target | * | 01291 // | critical | teams | + | 01292 // +------------------+-----------------+------------------------------------+ 01293 // | simd | parallel | | 01294 // | simd | for | | 01295 // | simd | for simd | | 01296 // | simd | master | | 01297 // | simd | critical | | 01298 // | simd | simd | | 01299 // | simd | sections | | 01300 // | simd | section | | 01301 // | simd | single | | 01302 // | simd | parallel for | | 01303 // | simd |parallel for simd| | 01304 // | simd |parallel sections| | 01305 // | simd | task | | 01306 // | simd | taskyield | | 01307 // | simd | barrier | | 01308 // | simd | taskwait | | 01309 // | simd | flush | | 01310 // | simd | ordered | | 01311 // | simd | atomic | | 01312 // | simd | target | | 01313 // | simd | teams | | 01314 // +------------------+-----------------+------------------------------------+ 01315 // | for simd | parallel | | 01316 // | for simd | for | | 01317 // | for simd | for simd | | 01318 // | for simd | master | | 01319 // | for simd | critical | | 01320 // | for simd | simd | | 01321 // | for simd | sections | | 01322 // | for simd | section | | 01323 // | for simd | single | | 01324 // | for simd | parallel for | | 01325 // | for simd |parallel for simd| | 01326 // | for simd |parallel sections| | 01327 // | for simd | task | | 01328 // | for simd | taskyield | | 01329 // | for simd | barrier | | 01330 // | for simd | taskwait | | 01331 // | for simd | flush | | 01332 // | for simd | ordered | | 01333 // | for simd | atomic | | 01334 // | for simd | target | | 01335 // | for simd | teams | | 01336 // +------------------+-----------------+------------------------------------+ 01337 // | parallel for simd| parallel | | 01338 // | parallel for simd| for | | 01339 // | parallel for simd| for simd | | 01340 // | parallel for simd| master | | 01341 // | parallel for simd| critical | | 01342 // | parallel for simd| simd | | 01343 // | parallel for simd| sections | | 01344 // | parallel for simd| section | | 01345 // | parallel for simd| single | | 01346 // | parallel for simd| parallel for | | 01347 // | parallel for simd|parallel for simd| | 01348 // | parallel for simd|parallel sections| | 01349 // | parallel for simd| task | | 01350 // | parallel for simd| taskyield | | 01351 // | parallel for simd| barrier | | 01352 // | parallel for simd| taskwait | | 01353 // | parallel for simd| flush | | 01354 // | parallel for simd| ordered | | 01355 // | parallel for simd| atomic | | 01356 // | parallel for simd| target | | 01357 // | parallel for simd| teams | | 01358 // +------------------+-----------------+------------------------------------+ 01359 // | sections | parallel | * | 01360 // | sections | for | + | 01361 // | sections | for simd | + | 01362 // | sections | master | + | 01363 // | sections | critical | * | 01364 // | sections | simd | * | 01365 // | sections | sections | + | 01366 // | sections | section | * | 01367 // | sections | single | + | 01368 // | sections | parallel for | * | 01369 // | sections |parallel for simd| * | 01370 // | sections |parallel sections| * | 01371 // | sections | task | * | 01372 // | sections | taskyield | * | 01373 // | sections | barrier | + | 01374 // | sections | taskwait | * | 01375 // | sections | flush | * | 01376 // | sections | ordered | + | 01377 // | sections | atomic | * | 01378 // | sections | target | * | 01379 // | sections | teams | + | 01380 // +------------------+-----------------+------------------------------------+ 01381 // | section | parallel | * | 01382 // | section | for | + | 01383 // | section | for simd | + | 01384 // | section | master | + | 01385 // | section | critical | * | 01386 // | section | simd | * | 01387 // | section | sections | + | 01388 // | section | section | + | 01389 // | section | single | + | 01390 // | section | parallel for | * | 01391 // | section |parallel for simd| * | 01392 // | section |parallel sections| * | 01393 // | section | task | * | 01394 // | section | taskyield | * | 01395 // | section | barrier | + | 01396 // | section | taskwait | * | 01397 // | section | flush | * | 01398 // | section | ordered | + | 01399 // | section | atomic | * | 01400 // | section | target | * | 01401 // | section | teams | + | 01402 // +------------------+-----------------+------------------------------------+ 01403 // | single | parallel | * | 01404 // | single | for | + | 01405 // | single | for simd | + | 01406 // | single | master | + | 01407 // | single | critical | * | 01408 // | single | simd | * | 01409 // | single | sections | + | 01410 // | single | section | + | 01411 // | single | single | + | 01412 // | single | parallel for | * | 01413 // | single |parallel for simd| * | 01414 // | single |parallel sections| * | 01415 // | single | task | * | 01416 // | single | taskyield | * | 01417 // | single | barrier | + | 01418 // | single | taskwait | * | 01419 // | single | flush | * | 01420 // | single | ordered | + | 01421 // | single | atomic | * | 01422 // | single | target | * | 01423 // | single | teams | + | 01424 // +------------------+-----------------+------------------------------------+ 01425 // | parallel for | parallel | * | 01426 // | parallel for | for | + | 01427 // | parallel for | for simd | + | 01428 // | parallel for | master | + | 01429 // | parallel for | critical | * | 01430 // | parallel for | simd | * | 01431 // | parallel for | sections | + | 01432 // | parallel for | section | + | 01433 // | parallel for | single | + | 01434 // | parallel for | parallel for | * | 01435 // | parallel for |parallel for simd| * | 01436 // | parallel for |parallel sections| * | 01437 // | parallel for | task | * | 01438 // | parallel for | taskyield | * | 01439 // | parallel for | barrier | + | 01440 // | parallel for | taskwait | * | 01441 // | parallel for | flush | * | 01442 // | parallel for | ordered | * (if construct is ordered) | 01443 // | parallel for | atomic | * | 01444 // | parallel for | target | * | 01445 // | parallel for | teams | + | 01446 // +------------------+-----------------+------------------------------------+ 01447 // | parallel sections| parallel | * | 01448 // | parallel sections| for | + | 01449 // | parallel sections| for simd | + | 01450 // | parallel sections| master | + | 01451 // | parallel sections| critical | + | 01452 // | parallel sections| simd | * | 01453 // | parallel sections| sections | + | 01454 // | parallel sections| section | * | 01455 // | parallel sections| single | + | 01456 // | parallel sections| parallel for | * | 01457 // | parallel sections|parallel for simd| * | 01458 // | parallel sections|parallel sections| * | 01459 // | parallel sections| task | * | 01460 // | parallel sections| taskyield | * | 01461 // | parallel sections| barrier | + | 01462 // | parallel sections| taskwait | * | 01463 // | parallel sections| flush | * | 01464 // | parallel sections| ordered | + | 01465 // | parallel sections| atomic | * | 01466 // | parallel sections| target | * | 01467 // | parallel sections| teams | + | 01468 // +------------------+-----------------+------------------------------------+ 01469 // | task | parallel | * | 01470 // | task | for | + | 01471 // | task | for simd | + | 01472 // | task | master | + | 01473 // | task | critical | * | 01474 // | task | simd | * | 01475 // | task | sections | + | 01476 // | task | section | + | 01477 // | task | single | + | 01478 // | task | parallel for | * | 01479 // | task |parallel for simd| * | 01480 // | task |parallel sections| * | 01481 // | task | task | * | 01482 // | task | taskyield | * | 01483 // | task | barrier | + | 01484 // | task | taskwait | * | 01485 // | task | flush | * | 01486 // | task | ordered | + | 01487 // | task | atomic | * | 01488 // | task | target | * | 01489 // | task | teams | + | 01490 // +------------------+-----------------+------------------------------------+ 01491 // | ordered | parallel | * | 01492 // | ordered | for | + | 01493 // | ordered | for simd | + | 01494 // | ordered | master | * | 01495 // | ordered | critical | * | 01496 // | ordered | simd | * | 01497 // | ordered | sections | + | 01498 // | ordered | section | + | 01499 // | ordered | single | + | 01500 // | ordered | parallel for | * | 01501 // | ordered |parallel for simd| * | 01502 // | ordered |parallel sections| * | 01503 // | ordered | task | * | 01504 // | ordered | taskyield | * | 01505 // | ordered | barrier | + | 01506 // | ordered | taskwait | * | 01507 // | ordered | flush | * | 01508 // | ordered | ordered | + | 01509 // | ordered | atomic | * | 01510 // | ordered | target | * | 01511 // | ordered | teams | + | 01512 // +------------------+-----------------+------------------------------------+ 01513 // | atomic | parallel | | 01514 // | atomic | for | | 01515 // | atomic | for simd | | 01516 // | atomic | master | | 01517 // | atomic | critical | | 01518 // | atomic | simd | | 01519 // | atomic | sections | | 01520 // | atomic | section | | 01521 // | atomic | single | | 01522 // | atomic | parallel for | | 01523 // | atomic |parallel for simd| | 01524 // | atomic |parallel sections| | 01525 // | atomic | task | | 01526 // | atomic | taskyield | | 01527 // | atomic | barrier | | 01528 // | atomic | taskwait | | 01529 // | atomic | flush | | 01530 // | atomic | ordered | | 01531 // | atomic | atomic | | 01532 // | atomic | target | | 01533 // | atomic | teams | | 01534 // +------------------+-----------------+------------------------------------+ 01535 // | target | parallel | * | 01536 // | target | for | * | 01537 // | target | for simd | * | 01538 // | target | master | * | 01539 // | target | critical | * | 01540 // | target | simd | * | 01541 // | target | sections | * | 01542 // | target | section | * | 01543 // | target | single | * | 01544 // | target | parallel for | * | 01545 // | target |parallel for simd| * | 01546 // | target |parallel sections| * | 01547 // | target | task | * | 01548 // | target | taskyield | * | 01549 // | target | barrier | * | 01550 // | target | taskwait | * | 01551 // | target | flush | * | 01552 // | target | ordered | * | 01553 // | target | atomic | * | 01554 // | target | target | * | 01555 // | target | teams | * | 01556 // +------------------+-----------------+------------------------------------+ 01557 // | teams | parallel | * | 01558 // | teams | for | + | 01559 // | teams | for simd | + | 01560 // | teams | master | + | 01561 // | teams | critical | + | 01562 // | teams | simd | + | 01563 // | teams | sections | + | 01564 // | teams | section | + | 01565 // | teams | single | + | 01566 // | teams | parallel for | * | 01567 // | teams |parallel for simd| * | 01568 // | teams |parallel sections| * | 01569 // | teams | task | + | 01570 // | teams | taskyield | + | 01571 // | teams | barrier | + | 01572 // | teams | taskwait | + | 01573 // | teams | flush | + | 01574 // | teams | ordered | + | 01575 // | teams | atomic | + | 01576 // | teams | target | + | 01577 // | teams | teams | + | 01578 // +------------------+-----------------+------------------------------------+ 01579 if (Stack->getCurScope()) { 01580 auto ParentRegion = Stack->getParentDirective(); 01581 bool NestingProhibited = false; 01582 bool CloseNesting = true; 01583 enum { 01584 NoRecommend, 01585 ShouldBeInParallelRegion, 01586 ShouldBeInOrderedRegion, 01587 ShouldBeInTargetRegion 01588 } Recommend = NoRecommend; 01589 if (isOpenMPSimdDirective(ParentRegion)) { 01590 // OpenMP [2.16, Nesting of Regions] 01591 // OpenMP constructs may not be nested inside a simd region. 01592 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd); 01593 return true; 01594 } 01595 if (ParentRegion == OMPD_atomic) { 01596 // OpenMP [2.16, Nesting of Regions] 01597 // OpenMP constructs may not be nested inside an atomic region. 01598 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 01599 return true; 01600 } 01601 if (CurrentRegion == OMPD_section) { 01602 // OpenMP [2.7.2, sections Construct, Restrictions] 01603 // Orphaned section directives are prohibited. That is, the section 01604 // directives must appear within the sections construct and must not be 01605 // encountered elsewhere in the sections region. 01606 if (ParentRegion != OMPD_sections && 01607 ParentRegion != OMPD_parallel_sections) { 01608 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 01609 << (ParentRegion != OMPD_unknown) 01610 << getOpenMPDirectiveName(ParentRegion); 01611 return true; 01612 } 01613 return false; 01614 } 01615 // Allow some constructs to be orphaned (they could be used in functions, 01616 // called from OpenMP regions with the required preconditions). 01617 if (ParentRegion == OMPD_unknown) 01618 return false; 01619 if (CurrentRegion == OMPD_master) { 01620 // OpenMP [2.16, Nesting of Regions] 01621 // A master region may not be closely nested inside a worksharing, 01622 // atomic, or explicit task region. 01623 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 01624 ParentRegion == OMPD_task; 01625 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 01626 // OpenMP [2.16, Nesting of Regions] 01627 // A critical region may not be nested (closely or otherwise) inside a 01628 // critical region with the same name. Note that this restriction is not 01629 // sufficient to prevent deadlock. 01630 SourceLocation PreviousCriticalLoc; 01631 bool DeadLock = 01632 Stack->hasDirective([CurrentName, &PreviousCriticalLoc]( 01633 OpenMPDirectiveKind K, 01634 const DeclarationNameInfo &DNI, 01635 SourceLocation Loc) 01636 ->bool { 01637 if (K == OMPD_critical && 01638 DNI.getName() == CurrentName.getName()) { 01639 PreviousCriticalLoc = Loc; 01640 return true; 01641 } else 01642 return false; 01643 }, 01644 false /* skip top directive */); 01645 if (DeadLock) { 01646 SemaRef.Diag(StartLoc, 01647 diag::err_omp_prohibited_region_critical_same_name) 01648 << CurrentName.getName(); 01649 if (PreviousCriticalLoc.isValid()) 01650 SemaRef.Diag(PreviousCriticalLoc, 01651 diag::note_omp_previous_critical_region); 01652 return true; 01653 } 01654 } else if (CurrentRegion == OMPD_barrier) { 01655 // OpenMP [2.16, Nesting of Regions] 01656 // A barrier region may not be closely nested inside a worksharing, 01657 // explicit task, critical, ordered, atomic, or master region. 01658 NestingProhibited = 01659 isOpenMPWorksharingDirective(ParentRegion) || 01660 ParentRegion == OMPD_task || ParentRegion == OMPD_master || 01661 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 01662 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 01663 !isOpenMPParallelDirective(CurrentRegion)) { 01664 // OpenMP [2.16, Nesting of Regions] 01665 // A worksharing region may not be closely nested inside a worksharing, 01666 // explicit task, critical, ordered, atomic, or master region. 01667 NestingProhibited = 01668 isOpenMPWorksharingDirective(ParentRegion) || 01669 ParentRegion == OMPD_task || ParentRegion == OMPD_master || 01670 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 01671 Recommend = ShouldBeInParallelRegion; 01672 } else if (CurrentRegion == OMPD_ordered) { 01673 // OpenMP [2.16, Nesting of Regions] 01674 // An ordered region may not be closely nested inside a critical, 01675 // atomic, or explicit task region. 01676 // An ordered region must be closely nested inside a loop region (or 01677 // parallel loop region) with an ordered clause. 01678 NestingProhibited = ParentRegion == OMPD_critical || 01679 ParentRegion == OMPD_task || 01680 !Stack->isParentOrderedRegion(); 01681 Recommend = ShouldBeInOrderedRegion; 01682 } else if (isOpenMPTeamsDirective(CurrentRegion)) { 01683 // OpenMP [2.16, Nesting of Regions] 01684 // If specified, a teams construct must be contained within a target 01685 // construct. 01686 NestingProhibited = ParentRegion != OMPD_target; 01687 Recommend = ShouldBeInTargetRegion; 01688 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); 01689 } 01690 if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) { 01691 // OpenMP [2.16, Nesting of Regions] 01692 // distribute, parallel, parallel sections, parallel workshare, and the 01693 // parallel loop and parallel loop SIMD constructs are the only OpenMP 01694 // constructs that can be closely nested in the teams region. 01695 // TODO: add distribute directive. 01696 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion); 01697 Recommend = ShouldBeInParallelRegion; 01698 } 01699 if (NestingProhibited) { 01700 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 01701 << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend 01702 << getOpenMPDirectiveName(CurrentRegion); 01703 return true; 01704 } 01705 } 01706 return false; 01707 } 01708 01709 StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, 01710 const DeclarationNameInfo &DirName, 01711 ArrayRef<OMPClause *> Clauses, 01712 Stmt *AStmt, 01713 SourceLocation StartLoc, 01714 SourceLocation EndLoc) { 01715 StmtResult Res = StmtError(); 01716 if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, StartLoc)) 01717 return StmtError(); 01718 01719 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 01720 llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA; 01721 bool ErrorFound = false; 01722 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 01723 if (AStmt) { 01724 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 01725 01726 // Check default data sharing attributes for referenced variables. 01727 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 01728 DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt()); 01729 if (DSAChecker.isErrorFound()) 01730 return StmtError(); 01731 // Generate list of implicitly defined firstprivate variables. 01732 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 01733 01734 if (!DSAChecker.getImplicitFirstprivate().empty()) { 01735 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 01736 DSAChecker.getImplicitFirstprivate(), SourceLocation(), 01737 SourceLocation(), SourceLocation())) { 01738 ClausesWithImplicit.push_back(Implicit); 01739 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 01740 DSAChecker.getImplicitFirstprivate().size(); 01741 } else 01742 ErrorFound = true; 01743 } 01744 } 01745 01746 switch (Kind) { 01747 case OMPD_parallel: 01748 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 01749 EndLoc); 01750 break; 01751 case OMPD_simd: 01752 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 01753 VarsWithInheritedDSA); 01754 break; 01755 case OMPD_for: 01756 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 01757 VarsWithInheritedDSA); 01758 break; 01759 case OMPD_for_simd: 01760 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 01761 EndLoc, VarsWithInheritedDSA); 01762 break; 01763 case OMPD_sections: 01764 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 01765 EndLoc); 01766 break; 01767 case OMPD_section: 01768 assert(ClausesWithImplicit.empty() && 01769 "No clauses are allowed for 'omp section' directive"); 01770 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 01771 break; 01772 case OMPD_single: 01773 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 01774 EndLoc); 01775 break; 01776 case OMPD_master: 01777 assert(ClausesWithImplicit.empty() && 01778 "No clauses are allowed for 'omp master' directive"); 01779 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 01780 break; 01781 case OMPD_critical: 01782 assert(ClausesWithImplicit.empty() && 01783 "No clauses are allowed for 'omp critical' directive"); 01784 Res = ActOnOpenMPCriticalDirective(DirName, AStmt, StartLoc, EndLoc); 01785 break; 01786 case OMPD_parallel_for: 01787 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 01788 EndLoc, VarsWithInheritedDSA); 01789 break; 01790 case OMPD_parallel_for_simd: 01791 Res = ActOnOpenMPParallelForSimdDirective( 01792 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 01793 break; 01794 case OMPD_parallel_sections: 01795 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 01796 StartLoc, EndLoc); 01797 break; 01798 case OMPD_task: 01799 Res = 01800 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 01801 break; 01802 case OMPD_taskyield: 01803 assert(ClausesWithImplicit.empty() && 01804 "No clauses are allowed for 'omp taskyield' directive"); 01805 assert(AStmt == nullptr && 01806 "No associated statement allowed for 'omp taskyield' directive"); 01807 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 01808 break; 01809 case OMPD_barrier: 01810 assert(ClausesWithImplicit.empty() && 01811 "No clauses are allowed for 'omp barrier' directive"); 01812 assert(AStmt == nullptr && 01813 "No associated statement allowed for 'omp barrier' directive"); 01814 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 01815 break; 01816 case OMPD_taskwait: 01817 assert(ClausesWithImplicit.empty() && 01818 "No clauses are allowed for 'omp taskwait' directive"); 01819 assert(AStmt == nullptr && 01820 "No associated statement allowed for 'omp taskwait' directive"); 01821 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 01822 break; 01823 case OMPD_flush: 01824 assert(AStmt == nullptr && 01825 "No associated statement allowed for 'omp flush' directive"); 01826 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 01827 break; 01828 case OMPD_ordered: 01829 assert(ClausesWithImplicit.empty() && 01830 "No clauses are allowed for 'omp ordered' directive"); 01831 Res = ActOnOpenMPOrderedDirective(AStmt, StartLoc, EndLoc); 01832 break; 01833 case OMPD_atomic: 01834 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 01835 EndLoc); 01836 break; 01837 case OMPD_teams: 01838 Res = 01839 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 01840 break; 01841 case OMPD_target: 01842 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 01843 EndLoc); 01844 break; 01845 case OMPD_threadprivate: 01846 llvm_unreachable("OpenMP Directive is not allowed"); 01847 case OMPD_unknown: 01848 llvm_unreachable("Unknown OpenMP directive"); 01849 } 01850 01851 for (auto P : VarsWithInheritedDSA) { 01852 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 01853 << P.first << P.second->getSourceRange(); 01854 } 01855 if (!VarsWithInheritedDSA.empty()) 01856 return StmtError(); 01857 01858 if (ErrorFound) 01859 return StmtError(); 01860 return Res; 01861 } 01862 01863 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 01864 Stmt *AStmt, 01865 SourceLocation StartLoc, 01866 SourceLocation EndLoc) { 01867 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 01868 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 01869 // 1.2.2 OpenMP Language Terminology 01870 // Structured block - An executable statement with a single entry at the 01871 // top and a single exit at the bottom. 01872 // The point of exit cannot be a branch out of the structured block. 01873 // longjmp() and throw() must not violate the entry/exit criteria. 01874 CS->getCapturedDecl()->setNothrow(); 01875 01876 getCurFunction()->setHasBranchProtectedScope(); 01877 01878 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 01879 AStmt); 01880 } 01881 01882 namespace { 01883 /// \brief Helper class for checking canonical form of the OpenMP loops and 01884 /// extracting iteration space of each loop in the loop nest, that will be used 01885 /// for IR generation. 01886 class OpenMPIterationSpaceChecker { 01887 /// \brief Reference to Sema. 01888 Sema &SemaRef; 01889 /// \brief A location for diagnostics (when there is no some better location). 01890 SourceLocation DefaultLoc; 01891 /// \brief A location for diagnostics (when increment is not compatible). 01892 SourceLocation ConditionLoc; 01893 /// \brief A source location for referring to loop init later. 01894 SourceRange InitSrcRange; 01895 /// \brief A source location for referring to condition later. 01896 SourceRange ConditionSrcRange; 01897 /// \brief A source location for referring to increment later. 01898 SourceRange IncrementSrcRange; 01899 /// \brief Loop variable. 01900 VarDecl *Var; 01901 /// \brief Reference to loop variable. 01902 DeclRefExpr *VarRef; 01903 /// \brief Lower bound (initializer for the var). 01904 Expr *LB; 01905 /// \brief Upper bound. 01906 Expr *UB; 01907 /// \brief Loop step (increment). 01908 Expr *Step; 01909 /// \brief This flag is true when condition is one of: 01910 /// Var < UB 01911 /// Var <= UB 01912 /// UB > Var 01913 /// UB >= Var 01914 bool TestIsLessOp; 01915 /// \brief This flag is true when condition is strict ( < or > ). 01916 bool TestIsStrictOp; 01917 /// \brief This flag is true when step is subtracted on each iteration. 01918 bool SubtractStep; 01919 01920 public: 01921 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 01922 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc), 01923 InitSrcRange(SourceRange()), ConditionSrcRange(SourceRange()), 01924 IncrementSrcRange(SourceRange()), Var(nullptr), VarRef(nullptr), 01925 LB(nullptr), UB(nullptr), Step(nullptr), TestIsLessOp(false), 01926 TestIsStrictOp(false), SubtractStep(false) {} 01927 /// \brief Check init-expr for canonical loop form and save loop counter 01928 /// variable - #Var and its initialization value - #LB. 01929 bool CheckInit(Stmt *S); 01930 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 01931 /// for less/greater and for strict/non-strict comparison. 01932 bool CheckCond(Expr *S); 01933 /// \brief Check incr-expr for canonical loop form and return true if it 01934 /// does not conform, otherwise save loop step (#Step). 01935 bool CheckInc(Expr *S); 01936 /// \brief Return the loop counter variable. 01937 VarDecl *GetLoopVar() const { return Var; } 01938 /// \brief Return the reference expression to loop counter variable. 01939 DeclRefExpr *GetLoopVarRefExpr() const { return VarRef; } 01940 /// \brief Source range of the loop init. 01941 SourceRange GetInitSrcRange() const { return InitSrcRange; } 01942 /// \brief Source range of the loop condition. 01943 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 01944 /// \brief Source range of the loop increment. 01945 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 01946 /// \brief True if the step should be subtracted. 01947 bool ShouldSubtractStep() const { return SubtractStep; } 01948 /// \brief Build the expression to calculate the number of iterations. 01949 Expr *BuildNumIterations(Scope *S, const bool LimitedType) const; 01950 /// \brief Build reference expression to the counter be used for codegen. 01951 Expr *BuildCounterVar() const; 01952 /// \brief Build initization of the counter be used for codegen. 01953 Expr *BuildCounterInit() const; 01954 /// \brief Build step of the counter be used for codegen. 01955 Expr *BuildCounterStep() const; 01956 /// \brief Return true if any expression is dependent. 01957 bool Dependent() const; 01958 01959 private: 01960 /// \brief Check the right-hand side of an assignment in the increment 01961 /// expression. 01962 bool CheckIncRHS(Expr *RHS); 01963 /// \brief Helper to set loop counter variable and its initializer. 01964 bool SetVarAndLB(VarDecl *NewVar, DeclRefExpr *NewVarRefExpr, Expr *NewLB); 01965 /// \brief Helper to set upper bound. 01966 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, const SourceRange &SR, 01967 const SourceLocation &SL); 01968 /// \brief Helper to set loop increment. 01969 bool SetStep(Expr *NewStep, bool Subtract); 01970 }; 01971 01972 bool OpenMPIterationSpaceChecker::Dependent() const { 01973 if (!Var) { 01974 assert(!LB && !UB && !Step); 01975 return false; 01976 } 01977 return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) || 01978 (UB && UB->isValueDependent()) || (Step && Step->isValueDependent()); 01979 } 01980 01981 bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, 01982 DeclRefExpr *NewVarRefExpr, 01983 Expr *NewLB) { 01984 // State consistency checking to ensure correct usage. 01985 assert(Var == nullptr && LB == nullptr && VarRef == nullptr && 01986 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 01987 if (!NewVar || !NewLB) 01988 return true; 01989 Var = NewVar; 01990 VarRef = NewVarRefExpr; 01991 LB = NewLB; 01992 return false; 01993 } 01994 01995 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 01996 const SourceRange &SR, 01997 const SourceLocation &SL) { 01998 // State consistency checking to ensure correct usage. 01999 assert(Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && 02000 !TestIsLessOp && !TestIsStrictOp); 02001 if (!NewUB) 02002 return true; 02003 UB = NewUB; 02004 TestIsLessOp = LessOp; 02005 TestIsStrictOp = StrictOp; 02006 ConditionSrcRange = SR; 02007 ConditionLoc = SL; 02008 return false; 02009 } 02010 02011 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 02012 // State consistency checking to ensure correct usage. 02013 assert(Var != nullptr && LB != nullptr && Step == nullptr); 02014 if (!NewStep) 02015 return true; 02016 if (!NewStep->isValueDependent()) { 02017 // Check that the step is integer expression. 02018 SourceLocation StepLoc = NewStep->getLocStart(); 02019 ExprResult Val = 02020 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep); 02021 if (Val.isInvalid()) 02022 return true; 02023 NewStep = Val.get(); 02024 02025 // OpenMP [2.6, Canonical Loop Form, Restrictions] 02026 // If test-expr is of form var relational-op b and relational-op is < or 02027 // <= then incr-expr must cause var to increase on each iteration of the 02028 // loop. If test-expr is of form var relational-op b and relational-op is 02029 // > or >= then incr-expr must cause var to decrease on each iteration of 02030 // the loop. 02031 // If test-expr is of form b relational-op var and relational-op is < or 02032 // <= then incr-expr must cause var to decrease on each iteration of the 02033 // loop. If test-expr is of form b relational-op var and relational-op is 02034 // > or >= then incr-expr must cause var to increase on each iteration of 02035 // the loop. 02036 llvm::APSInt Result; 02037 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 02038 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 02039 bool IsConstNeg = 02040 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 02041 bool IsConstPos = 02042 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 02043 bool IsConstZero = IsConstant && !Result.getBoolValue(); 02044 if (UB && (IsConstZero || 02045 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 02046 : (IsConstPos || (IsUnsigned && !Subtract))))) { 02047 SemaRef.Diag(NewStep->getExprLoc(), 02048 diag::err_omp_loop_incr_not_compatible) 02049 << Var << TestIsLessOp << NewStep->getSourceRange(); 02050 SemaRef.Diag(ConditionLoc, 02051 diag::note_omp_loop_cond_requres_compatible_incr) 02052 << TestIsLessOp << ConditionSrcRange; 02053 return true; 02054 } 02055 if (TestIsLessOp == Subtract) { 02056 NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, 02057 NewStep).get(); 02058 Subtract = !Subtract; 02059 } 02060 } 02061 02062 Step = NewStep; 02063 SubtractStep = Subtract; 02064 return false; 02065 } 02066 02067 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S) { 02068 // Check init-expr for canonical loop form and save loop counter 02069 // variable - #Var and its initialization value - #LB. 02070 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 02071 // var = lb 02072 // integer-type var = lb 02073 // random-access-iterator-type var = lb 02074 // pointer-type var = lb 02075 // 02076 if (!S) { 02077 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 02078 return true; 02079 } 02080 InitSrcRange = S->getSourceRange(); 02081 if (Expr *E = dyn_cast<Expr>(S)) 02082 S = E->IgnoreParens(); 02083 if (auto BO = dyn_cast<BinaryOperator>(S)) { 02084 if (BO->getOpcode() == BO_Assign) 02085 if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens())) 02086 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, 02087 BO->getRHS()); 02088 } else if (auto DS = dyn_cast<DeclStmt>(S)) { 02089 if (DS->isSingleDecl()) { 02090 if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 02091 if (Var->hasInit()) { 02092 // Accept non-canonical init form here but emit ext. warning. 02093 if (Var->getInitStyle() != VarDecl::CInit) 02094 SemaRef.Diag(S->getLocStart(), 02095 diag::ext_omp_loop_not_canonical_init) 02096 << S->getSourceRange(); 02097 return SetVarAndLB(Var, nullptr, Var->getInit()); 02098 } 02099 } 02100 } 02101 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) 02102 if (CE->getOperator() == OO_Equal) 02103 if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0))) 02104 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, 02105 CE->getArg(1)); 02106 02107 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 02108 << S->getSourceRange(); 02109 return true; 02110 } 02111 02112 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 02113 /// variable (which may be the loop variable) if possible. 02114 static const VarDecl *GetInitVarDecl(const Expr *E) { 02115 if (!E) 02116 return nullptr; 02117 E = E->IgnoreParenImpCasts(); 02118 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 02119 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 02120 if (Ctor->isCopyConstructor() && CE->getNumArgs() == 1 && 02121 CE->getArg(0) != nullptr) 02122 E = CE->getArg(0)->IgnoreParenImpCasts(); 02123 auto DRE = dyn_cast_or_null<DeclRefExpr>(E); 02124 if (!DRE) 02125 return nullptr; 02126 return dyn_cast<VarDecl>(DRE->getDecl()); 02127 } 02128 02129 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 02130 // Check test-expr for canonical form, save upper-bound UB, flags for 02131 // less/greater and for strict/non-strict comparison. 02132 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 02133 // var relational-op b 02134 // b relational-op var 02135 // 02136 if (!S) { 02137 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var; 02138 return true; 02139 } 02140 S = S->IgnoreParenImpCasts(); 02141 SourceLocation CondLoc = S->getLocStart(); 02142 if (auto BO = dyn_cast<BinaryOperator>(S)) { 02143 if (BO->isRelationalOp()) { 02144 if (GetInitVarDecl(BO->getLHS()) == Var) 02145 return SetUB(BO->getRHS(), 02146 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 02147 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 02148 BO->getSourceRange(), BO->getOperatorLoc()); 02149 if (GetInitVarDecl(BO->getRHS()) == Var) 02150 return SetUB(BO->getLHS(), 02151 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 02152 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 02153 BO->getSourceRange(), BO->getOperatorLoc()); 02154 } 02155 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 02156 if (CE->getNumArgs() == 2) { 02157 auto Op = CE->getOperator(); 02158 switch (Op) { 02159 case OO_Greater: 02160 case OO_GreaterEqual: 02161 case OO_Less: 02162 case OO_LessEqual: 02163 if (GetInitVarDecl(CE->getArg(0)) == Var) 02164 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 02165 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 02166 CE->getOperatorLoc()); 02167 if (GetInitVarDecl(CE->getArg(1)) == Var) 02168 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 02169 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 02170 CE->getOperatorLoc()); 02171 break; 02172 default: 02173 break; 02174 } 02175 } 02176 } 02177 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 02178 << S->getSourceRange() << Var; 02179 return true; 02180 } 02181 02182 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 02183 // RHS of canonical loop form increment can be: 02184 // var + incr 02185 // incr + var 02186 // var - incr 02187 // 02188 RHS = RHS->IgnoreParenImpCasts(); 02189 if (auto BO = dyn_cast<BinaryOperator>(RHS)) { 02190 if (BO->isAdditiveOp()) { 02191 bool IsAdd = BO->getOpcode() == BO_Add; 02192 if (GetInitVarDecl(BO->getLHS()) == Var) 02193 return SetStep(BO->getRHS(), !IsAdd); 02194 if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var) 02195 return SetStep(BO->getLHS(), false); 02196 } 02197 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 02198 bool IsAdd = CE->getOperator() == OO_Plus; 02199 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 02200 if (GetInitVarDecl(CE->getArg(0)) == Var) 02201 return SetStep(CE->getArg(1), !IsAdd); 02202 if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var) 02203 return SetStep(CE->getArg(0), false); 02204 } 02205 } 02206 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 02207 << RHS->getSourceRange() << Var; 02208 return true; 02209 } 02210 02211 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 02212 // Check incr-expr for canonical loop form and return true if it 02213 // does not conform. 02214 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 02215 // ++var 02216 // var++ 02217 // --var 02218 // var-- 02219 // var += incr 02220 // var -= incr 02221 // var = var + incr 02222 // var = incr + var 02223 // var = var - incr 02224 // 02225 if (!S) { 02226 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var; 02227 return true; 02228 } 02229 IncrementSrcRange = S->getSourceRange(); 02230 S = S->IgnoreParens(); 02231 if (auto UO = dyn_cast<UnaryOperator>(S)) { 02232 if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var) 02233 return SetStep( 02234 SemaRef.ActOnIntegerConstant(UO->getLocStart(), 02235 (UO->isDecrementOp() ? -1 : 1)).get(), 02236 false); 02237 } else if (auto BO = dyn_cast<BinaryOperator>(S)) { 02238 switch (BO->getOpcode()) { 02239 case BO_AddAssign: 02240 case BO_SubAssign: 02241 if (GetInitVarDecl(BO->getLHS()) == Var) 02242 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 02243 break; 02244 case BO_Assign: 02245 if (GetInitVarDecl(BO->getLHS()) == Var) 02246 return CheckIncRHS(BO->getRHS()); 02247 break; 02248 default: 02249 break; 02250 } 02251 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 02252 switch (CE->getOperator()) { 02253 case OO_PlusPlus: 02254 case OO_MinusMinus: 02255 if (GetInitVarDecl(CE->getArg(0)) == Var) 02256 return SetStep( 02257 SemaRef.ActOnIntegerConstant( 02258 CE->getLocStart(), 02259 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(), 02260 false); 02261 break; 02262 case OO_PlusEqual: 02263 case OO_MinusEqual: 02264 if (GetInitVarDecl(CE->getArg(0)) == Var) 02265 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 02266 break; 02267 case OO_Equal: 02268 if (GetInitVarDecl(CE->getArg(0)) == Var) 02269 return CheckIncRHS(CE->getArg(1)); 02270 break; 02271 default: 02272 break; 02273 } 02274 } 02275 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 02276 << S->getSourceRange() << Var; 02277 return true; 02278 } 02279 02280 /// \brief Build the expression to calculate the number of iterations. 02281 Expr * 02282 OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, 02283 const bool LimitedType) const { 02284 ExprResult Diff; 02285 if (Var->getType()->isIntegerType() || Var->getType()->isPointerType() || 02286 SemaRef.getLangOpts().CPlusPlus) { 02287 // Upper - Lower 02288 Expr *Upper = TestIsLessOp ? UB : LB; 02289 Expr *Lower = TestIsLessOp ? LB : UB; 02290 02291 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 02292 02293 if (!Diff.isUsable() && Var->getType()->getAsCXXRecordDecl()) { 02294 // BuildBinOp already emitted error, this one is to point user to upper 02295 // and lower bound, and to tell what is passed to 'operator-'. 02296 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 02297 << Upper->getSourceRange() << Lower->getSourceRange(); 02298 return nullptr; 02299 } 02300 } 02301 02302 if (!Diff.isUsable()) 02303 return nullptr; 02304 02305 // Upper - Lower [- 1] 02306 if (TestIsStrictOp) 02307 Diff = SemaRef.BuildBinOp( 02308 S, DefaultLoc, BO_Sub, Diff.get(), 02309 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 02310 if (!Diff.isUsable()) 02311 return nullptr; 02312 02313 // Upper - Lower [- 1] + Step 02314 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), 02315 Step->IgnoreImplicit()); 02316 if (!Diff.isUsable()) 02317 return nullptr; 02318 02319 // Parentheses (for dumping/debugging purposes only). 02320 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 02321 if (!Diff.isUsable()) 02322 return nullptr; 02323 02324 // (Upper - Lower [- 1] + Step) / Step 02325 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), 02326 Step->IgnoreImplicit()); 02327 if (!Diff.isUsable()) 02328 return nullptr; 02329 02330 // OpenMP runtime requires 32-bit or 64-bit loop variables. 02331 if (LimitedType) { 02332 auto &C = SemaRef.Context; 02333 QualType Type = Diff.get()->getType(); 02334 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 02335 if (NewSize != C.getTypeSize(Type)) { 02336 if (NewSize < C.getTypeSize(Type)) { 02337 assert(NewSize == 64 && "incorrect loop var size"); 02338 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 02339 << InitSrcRange << ConditionSrcRange; 02340 } 02341 QualType NewType = C.getIntTypeForBitwidth( 02342 NewSize, Type->hasSignedIntegerRepresentation()); 02343 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 02344 Sema::AA_Converting, true); 02345 if (!Diff.isUsable()) 02346 return nullptr; 02347 } 02348 } 02349 02350 return Diff.get(); 02351 } 02352 02353 /// \brief Build reference expression to the counter be used for codegen. 02354 Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const { 02355 return DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), 02356 GetIncrementSrcRange().getBegin(), Var, false, 02357 DefaultLoc, Var->getType(), VK_LValue); 02358 } 02359 02360 /// \brief Build initization of the counter be used for codegen. 02361 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 02362 02363 /// \brief Build step of the counter be used for codegen. 02364 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 02365 02366 /// \brief Iteration space of a single for loop. 02367 struct LoopIterationSpace { 02368 /// \brief This expression calculates the number of iterations in the loop. 02369 /// It is always possible to calculate it before starting the loop. 02370 Expr *NumIterations; 02371 /// \brief The loop counter variable. 02372 Expr *CounterVar; 02373 /// \brief This is initializer for the initial value of #CounterVar. 02374 Expr *CounterInit; 02375 /// \brief This is step for the #CounterVar used to generate its update: 02376 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 02377 Expr *CounterStep; 02378 /// \brief Should step be subtracted? 02379 bool Subtract; 02380 /// \brief Source range of the loop init. 02381 SourceRange InitSrcRange; 02382 /// \brief Source range of the loop condition. 02383 SourceRange CondSrcRange; 02384 /// \brief Source range of the loop increment. 02385 SourceRange IncSrcRange; 02386 }; 02387 02388 /// \brief The resulting expressions built for the OpenMP loop CodeGen for the 02389 /// whole collapsed loop nest. See class OMPLoopDirective for their description. 02390 struct BuiltLoopExprs { 02391 Expr *IterationVarRef; 02392 Expr *LastIteration; 02393 Expr *CalcLastIteration; 02394 Expr *PreCond; 02395 Expr *Cond; 02396 Expr *SeparatedCond; 02397 Expr *Init; 02398 Expr *Inc; 02399 SmallVector<Expr *, 4> Counters; 02400 SmallVector<Expr *, 4> Updates; 02401 SmallVector<Expr *, 4> Finals; 02402 02403 bool builtAll() { 02404 return IterationVarRef != nullptr && LastIteration != nullptr && 02405 PreCond != nullptr && Cond != nullptr && SeparatedCond != nullptr && 02406 Init != nullptr && Inc != nullptr; 02407 } 02408 void clear(unsigned size) { 02409 IterationVarRef = nullptr; 02410 LastIteration = nullptr; 02411 CalcLastIteration = nullptr; 02412 PreCond = nullptr; 02413 Cond = nullptr; 02414 SeparatedCond = nullptr; 02415 Init = nullptr; 02416 Inc = nullptr; 02417 Counters.resize(size); 02418 Updates.resize(size); 02419 Finals.resize(size); 02420 for (unsigned i = 0; i < size; ++i) { 02421 Counters[i] = nullptr; 02422 Updates[i] = nullptr; 02423 Finals[i] = nullptr; 02424 } 02425 } 02426 }; 02427 02428 } // namespace 02429 02430 /// \brief Called on a for stmt to check and extract its iteration space 02431 /// for further processing (such as collapsing). 02432 static bool CheckOpenMPIterationSpace( 02433 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 02434 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 02435 Expr *NestedLoopCountExpr, 02436 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, 02437 LoopIterationSpace &ResultIterSpace) { 02438 // OpenMP [2.6, Canonical Loop Form] 02439 // for (init-expr; test-expr; incr-expr) structured-block 02440 auto For = dyn_cast_or_null<ForStmt>(S); 02441 if (!For) { 02442 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 02443 << (NestedLoopCountExpr != nullptr) << getOpenMPDirectiveName(DKind) 02444 << NestedLoopCount << (CurrentNestedLoopCount > 0) 02445 << CurrentNestedLoopCount; 02446 if (NestedLoopCount > 1) 02447 SemaRef.Diag(NestedLoopCountExpr->getExprLoc(), 02448 diag::note_omp_collapse_expr) 02449 << NestedLoopCountExpr->getSourceRange(); 02450 return true; 02451 } 02452 assert(For->getBody()); 02453 02454 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 02455 02456 // Check init. 02457 auto Init = For->getInit(); 02458 if (ISC.CheckInit(Init)) { 02459 return true; 02460 } 02461 02462 bool HasErrors = false; 02463 02464 // Check loop variable's type. 02465 auto Var = ISC.GetLoopVar(); 02466 02467 // OpenMP [2.6, Canonical Loop Form] 02468 // Var is one of the following: 02469 // A variable of signed or unsigned integer type. 02470 // For C++, a variable of a random access iterator type. 02471 // For C, a variable of a pointer type. 02472 auto VarType = Var->getType(); 02473 if (!VarType->isDependentType() && !VarType->isIntegerType() && 02474 !VarType->isPointerType() && 02475 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 02476 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 02477 << SemaRef.getLangOpts().CPlusPlus; 02478 HasErrors = true; 02479 } 02480 02481 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a 02482 // Construct 02483 // The loop iteration variable(s) in the associated for-loop(s) of a for or 02484 // parallel for construct is (are) private. 02485 // The loop iteration variable in the associated for-loop of a simd construct 02486 // with just one associated for-loop is linear with a constant-linear-step 02487 // that is the increment of the associated for-loop. 02488 // Exclude loop var from the list of variables with implicitly defined data 02489 // sharing attributes. 02490 VarsWithImplicitDSA.erase(Var); 02491 02492 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in 02493 // a Construct, C/C++]. 02494 // The loop iteration variable in the associated for-loop of a simd construct 02495 // with just one associated for-loop may be listed in a linear clause with a 02496 // constant-linear-step that is the increment of the associated for-loop. 02497 // The loop iteration variable(s) in the associated for-loop(s) of a for or 02498 // parallel for construct may be listed in a private or lastprivate clause. 02499 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var, false); 02500 auto LoopVarRefExpr = ISC.GetLoopVarRefExpr(); 02501 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 02502 // declared in the loop and it is predetermined as a private. 02503 auto PredeterminedCKind = 02504 isOpenMPSimdDirective(DKind) 02505 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 02506 : OMPC_private; 02507 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 02508 DVar.CKind != PredeterminedCKind) || 02509 (isOpenMPWorksharingDirective(DKind) && !isOpenMPSimdDirective(DKind) && 02510 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private && 02511 DVar.CKind != OMPC_lastprivate)) && 02512 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 02513 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 02514 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 02515 << getOpenMPClauseName(PredeterminedCKind); 02516 ReportOriginalDSA(SemaRef, &DSA, Var, DVar, true); 02517 HasErrors = true; 02518 } else if (LoopVarRefExpr != nullptr) { 02519 // Make the loop iteration variable private (for worksharing constructs), 02520 // linear (for simd directives with the only one associated loop) or 02521 // lastprivate (for simd directives with several collapsed loops). 02522 // FIXME: the next check and error message must be removed once the 02523 // capturing of global variables in loops is fixed. 02524 if (DVar.CKind == OMPC_unknown) 02525 DVar = DSA.hasDSA(Var, isOpenMPPrivate, MatchesAlways(), 02526 /*FromParent=*/false); 02527 if (!Var->hasLocalStorage() && DVar.CKind == OMPC_unknown) { 02528 SemaRef.Diag(Init->getLocStart(), diag::err_omp_global_loop_var_dsa) 02529 << getOpenMPClauseName(PredeterminedCKind) 02530 << getOpenMPDirectiveName(DKind); 02531 HasErrors = true; 02532 } else 02533 DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind); 02534 } 02535 02536 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 02537 02538 // Check test-expr. 02539 HasErrors |= ISC.CheckCond(For->getCond()); 02540 02541 // Check incr-expr. 02542 HasErrors |= ISC.CheckInc(For->getInc()); 02543 02544 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 02545 return HasErrors; 02546 02547 // Build the loop's iteration space representation. 02548 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 02549 DSA.getCurScope(), /* LimitedType */ isOpenMPWorksharingDirective(DKind)); 02550 ResultIterSpace.CounterVar = ISC.BuildCounterVar(); 02551 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 02552 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 02553 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 02554 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 02555 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 02556 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 02557 02558 HasErrors |= (ResultIterSpace.NumIterations == nullptr || 02559 ResultIterSpace.CounterVar == nullptr || 02560 ResultIterSpace.CounterInit == nullptr || 02561 ResultIterSpace.CounterStep == nullptr); 02562 02563 return HasErrors; 02564 } 02565 02566 /// \brief Build a variable declaration for OpenMP loop iteration variable. 02567 static VarDecl *BuildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 02568 StringRef Name) { 02569 DeclContext *DC = SemaRef.CurContext; 02570 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 02571 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 02572 VarDecl *Decl = 02573 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 02574 Decl->setImplicit(); 02575 return Decl; 02576 } 02577 02578 /// \brief Build 'VarRef = Start + Iter * Step'. 02579 static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, 02580 SourceLocation Loc, ExprResult VarRef, 02581 ExprResult Start, ExprResult Iter, 02582 ExprResult Step, bool Subtract) { 02583 // Add parentheses (for debugging purposes only). 02584 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 02585 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 02586 !Step.isUsable()) 02587 return ExprError(); 02588 02589 ExprResult Update = SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), 02590 Step.get()->IgnoreImplicit()); 02591 if (!Update.isUsable()) 02592 return ExprError(); 02593 02594 // Build 'VarRef = Start + Iter * Step'. 02595 Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add), 02596 Start.get()->IgnoreImplicit(), Update.get()); 02597 if (!Update.isUsable()) 02598 return ExprError(); 02599 02600 Update = SemaRef.PerformImplicitConversion( 02601 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 02602 if (!Update.isUsable()) 02603 return ExprError(); 02604 02605 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 02606 return Update; 02607 } 02608 02609 /// \brief Convert integer expression \a E to make it have at least \a Bits 02610 /// bits. 02611 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, 02612 Sema &SemaRef) { 02613 if (E == nullptr) 02614 return ExprError(); 02615 auto &C = SemaRef.Context; 02616 QualType OldType = E->getType(); 02617 unsigned HasBits = C.getTypeSize(OldType); 02618 if (HasBits >= Bits) 02619 return ExprResult(E); 02620 // OK to convert to signed, because new type has more bits than old. 02621 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 02622 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 02623 true); 02624 } 02625 02626 /// \brief Check if the given expression \a E is a constant integer that fits 02627 /// into \a Bits bits. 02628 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 02629 if (E == nullptr) 02630 return false; 02631 llvm::APSInt Result; 02632 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 02633 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 02634 return false; 02635 } 02636 02637 /// \brief Called on a for stmt to check itself and nested loops (if any). 02638 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 02639 /// number of collapsed loops otherwise. 02640 static unsigned 02641 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, 02642 Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, 02643 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, 02644 BuiltLoopExprs &Built) { 02645 unsigned NestedLoopCount = 1; 02646 if (NestedLoopCountExpr) { 02647 // Found 'collapse' clause - calculate collapse number. 02648 llvm::APSInt Result; 02649 if (NestedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 02650 NestedLoopCount = Result.getLimitedValue(); 02651 } 02652 // This is helper routine for loop directives (e.g., 'for', 'simd', 02653 // 'for simd', etc.). 02654 SmallVector<LoopIterationSpace, 4> IterSpaces; 02655 IterSpaces.resize(NestedLoopCount); 02656 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 02657 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 02658 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 02659 NestedLoopCount, NestedLoopCountExpr, 02660 VarsWithImplicitDSA, IterSpaces[Cnt])) 02661 return 0; 02662 // Move on to the next nested for loop, or to the loop body. 02663 // OpenMP [2.8.1, simd construct, Restrictions] 02664 // All loops associated with the construct must be perfectly nested; that 02665 // is, there must be no intervening code nor any OpenMP directive between 02666 // any two loops. 02667 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 02668 } 02669 02670 Built.clear(/* size */ NestedLoopCount); 02671 02672 if (SemaRef.CurContext->isDependentContext()) 02673 return NestedLoopCount; 02674 02675 // An example of what is generated for the following code: 02676 // 02677 // #pragma omp simd collapse(2) 02678 // for (i = 0; i < NI; ++i) 02679 // for (j = J0; j < NJ; j+=2) { 02680 // <loop body> 02681 // } 02682 // 02683 // We generate the code below. 02684 // Note: the loop body may be outlined in CodeGen. 02685 // Note: some counters may be C++ classes, operator- is used to find number of 02686 // iterations and operator+= to calculate counter value. 02687 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 02688 // or i64 is currently supported). 02689 // 02690 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 02691 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 02692 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 02693 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 02694 // // similar updates for vars in clauses (e.g. 'linear') 02695 // <loop body (using local i and j)> 02696 // } 02697 // i = NI; // assign final values of counters 02698 // j = NJ; 02699 // 02700 02701 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 02702 // the iteration counts of the collapsed for loops. 02703 auto N0 = IterSpaces[0].NumIterations; 02704 ExprResult LastIteration32 = WidenIterationCount(32 /* Bits */, N0, SemaRef); 02705 ExprResult LastIteration64 = WidenIterationCount(64 /* Bits */, N0, SemaRef); 02706 02707 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 02708 return NestedLoopCount; 02709 02710 auto &C = SemaRef.Context; 02711 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 02712 02713 Scope *CurScope = DSA.getCurScope(); 02714 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 02715 auto N = IterSpaces[Cnt].NumIterations; 02716 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 02717 if (LastIteration32.isUsable()) 02718 LastIteration32 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, 02719 LastIteration32.get(), N); 02720 if (LastIteration64.isUsable()) 02721 LastIteration64 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, 02722 LastIteration64.get(), N); 02723 } 02724 02725 // Choose either the 32-bit or 64-bit version. 02726 ExprResult LastIteration = LastIteration64; 02727 if (LastIteration32.isUsable() && 02728 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 02729 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 02730 FitsInto( 02731 32 /* Bits */, 02732 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 02733 LastIteration64.get(), SemaRef))) 02734 LastIteration = LastIteration32; 02735 02736 if (!LastIteration.isUsable()) 02737 return 0; 02738 02739 // Save the number of iterations. 02740 ExprResult NumIterations = LastIteration; 02741 { 02742 LastIteration = SemaRef.BuildBinOp( 02743 CurScope, SourceLocation(), BO_Sub, LastIteration.get(), 02744 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 02745 if (!LastIteration.isUsable()) 02746 return 0; 02747 } 02748 02749 // Calculate the last iteration number beforehand instead of doing this on 02750 // each iteration. Do not do this if the number of iterations may be kfold-ed. 02751 llvm::APSInt Result; 02752 bool IsConstant = 02753 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 02754 ExprResult CalcLastIteration; 02755 if (!IsConstant) { 02756 SourceLocation SaveLoc; 02757 VarDecl *SaveVar = 02758 BuildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(), 02759 ".omp.last.iteration"); 02760 ExprResult SaveRef = SemaRef.BuildDeclRefExpr( 02761 SaveVar, LastIteration.get()->getType(), VK_LValue, SaveLoc); 02762 CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign, 02763 SaveRef.get(), LastIteration.get()); 02764 LastIteration = SaveRef; 02765 02766 // Prepare SaveRef + 1. 02767 NumIterations = SemaRef.BuildBinOp( 02768 CurScope, SaveLoc, BO_Add, SaveRef.get(), 02769 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 02770 if (!NumIterations.isUsable()) 02771 return 0; 02772 } 02773 02774 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 02775 02776 // Precondition tests if there is at least one iteration (LastIteration > 0). 02777 ExprResult PreCond = SemaRef.BuildBinOp( 02778 CurScope, InitLoc, BO_GT, LastIteration.get(), 02779 SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get()); 02780 02781 // Build the iteration variable and its initialization to zero before loop. 02782 ExprResult IV; 02783 ExprResult Init; 02784 { 02785 VarDecl *IVDecl = BuildVarDecl(SemaRef, InitLoc, 02786 LastIteration.get()->getType(), ".omp.iv"); 02787 IV = SemaRef.BuildDeclRefExpr(IVDecl, LastIteration.get()->getType(), 02788 VK_LValue, InitLoc); 02789 Init = SemaRef.BuildBinOp( 02790 CurScope, InitLoc, BO_Assign, IV.get(), 02791 SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get()); 02792 } 02793 02794 // Loop condition (IV < NumIterations) 02795 SourceLocation CondLoc; 02796 ExprResult Cond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 02797 NumIterations.get()); 02798 // Loop condition with 1 iteration separated (IV < LastIteration) 02799 ExprResult SeparatedCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, 02800 IV.get(), LastIteration.get()); 02801 02802 // Loop increment (IV = IV + 1) 02803 SourceLocation IncLoc; 02804 ExprResult Inc = 02805 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 02806 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 02807 if (!Inc.isUsable()) 02808 return 0; 02809 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 02810 02811 // Build updates and final values of the loop counters. 02812 bool HasErrors = false; 02813 Built.Counters.resize(NestedLoopCount); 02814 Built.Updates.resize(NestedLoopCount); 02815 Built.Finals.resize(NestedLoopCount); 02816 { 02817 ExprResult Div; 02818 // Go from inner nested loop to outer. 02819 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 02820 LoopIterationSpace &IS = IterSpaces[Cnt]; 02821 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 02822 // Build: Iter = (IV / Div) % IS.NumIters 02823 // where Div is product of previous iterations' IS.NumIters. 02824 ExprResult Iter; 02825 if (Div.isUsable()) { 02826 Iter = 02827 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 02828 } else { 02829 Iter = IV; 02830 assert((Cnt == (int)NestedLoopCount - 1) && 02831 "unusable div expected on first iteration only"); 02832 } 02833 02834 if (Cnt != 0 && Iter.isUsable()) 02835 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 02836 IS.NumIterations); 02837 if (!Iter.isUsable()) { 02838 HasErrors = true; 02839 break; 02840 } 02841 02842 // Build update: IS.CounterVar = IS.Start + Iter * IS.Step 02843 ExprResult Update = 02844 BuildCounterUpdate(SemaRef, CurScope, UpdLoc, IS.CounterVar, 02845 IS.CounterInit, Iter, IS.CounterStep, IS.Subtract); 02846 if (!Update.isUsable()) { 02847 HasErrors = true; 02848 break; 02849 } 02850 02851 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 02852 ExprResult Final = BuildCounterUpdate( 02853 SemaRef, CurScope, UpdLoc, IS.CounterVar, IS.CounterInit, 02854 IS.NumIterations, IS.CounterStep, IS.Subtract); 02855 if (!Final.isUsable()) { 02856 HasErrors = true; 02857 break; 02858 } 02859 02860 // Build Div for the next iteration: Div <- Div * IS.NumIters 02861 if (Cnt != 0) { 02862 if (Div.isUnset()) 02863 Div = IS.NumIterations; 02864 else 02865 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 02866 IS.NumIterations); 02867 02868 // Add parentheses (for debugging purposes only). 02869 if (Div.isUsable()) 02870 Div = SemaRef.ActOnParenExpr(UpdLoc, UpdLoc, Div.get()); 02871 if (!Div.isUsable()) { 02872 HasErrors = true; 02873 break; 02874 } 02875 } 02876 if (!Update.isUsable() || !Final.isUsable()) { 02877 HasErrors = true; 02878 break; 02879 } 02880 // Save results 02881 Built.Counters[Cnt] = IS.CounterVar; 02882 Built.Updates[Cnt] = Update.get(); 02883 Built.Finals[Cnt] = Final.get(); 02884 } 02885 } 02886 02887 if (HasErrors) 02888 return 0; 02889 02890 // Save results 02891 Built.IterationVarRef = IV.get(); 02892 Built.LastIteration = LastIteration.get(); 02893 Built.CalcLastIteration = CalcLastIteration.get(); 02894 Built.PreCond = PreCond.get(); 02895 Built.Cond = Cond.get(); 02896 Built.SeparatedCond = SeparatedCond.get(); 02897 Built.Init = Init.get(); 02898 Built.Inc = Inc.get(); 02899 02900 return NestedLoopCount; 02901 } 02902 02903 static Expr *GetCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 02904 auto CollapseFilter = [](const OMPClause *C) -> bool { 02905 return C->getClauseKind() == OMPC_collapse; 02906 }; 02907 OMPExecutableDirective::filtered_clause_iterator<decltype(CollapseFilter)> I( 02908 Clauses, CollapseFilter); 02909 if (I) 02910 return cast<OMPCollapseClause>(*I)->getNumForLoops(); 02911 return nullptr; 02912 } 02913 02914 StmtResult Sema::ActOnOpenMPSimdDirective( 02915 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 02916 SourceLocation EndLoc, 02917 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 02918 BuiltLoopExprs B; 02919 // In presence of clause 'collapse', it will define the nested loops number. 02920 unsigned NestedLoopCount = 02921 CheckOpenMPLoop(OMPD_simd, GetCollapseNumberExpr(Clauses), AStmt, *this, 02922 *DSAStack, VarsWithImplicitDSA, B); 02923 if (NestedLoopCount == 0) 02924 return StmtError(); 02925 02926 assert((CurContext->isDependentContext() || B.builtAll()) && 02927 "omp simd loop exprs were not built"); 02928 02929 getCurFunction()->setHasBranchProtectedScope(); 02930 return OMPSimdDirective::Create( 02931 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, 02932 B.IterationVarRef, B.LastIteration, B.CalcLastIteration, B.PreCond, 02933 B.Cond, B.SeparatedCond, B.Init, B.Inc, B.Counters, B.Updates, B.Finals); 02934 } 02935 02936 StmtResult Sema::ActOnOpenMPForDirective( 02937 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 02938 SourceLocation EndLoc, 02939 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 02940 BuiltLoopExprs B; 02941 // In presence of clause 'collapse', it will define the nested loops number. 02942 unsigned NestedLoopCount = 02943 CheckOpenMPLoop(OMPD_for, GetCollapseNumberExpr(Clauses), AStmt, *this, 02944 *DSAStack, VarsWithImplicitDSA, B); 02945 if (NestedLoopCount == 0) 02946 return StmtError(); 02947 02948 assert((CurContext->isDependentContext() || B.builtAll()) && 02949 "omp for loop exprs were not built"); 02950 02951 getCurFunction()->setHasBranchProtectedScope(); 02952 return OMPForDirective::Create( 02953 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, 02954 B.IterationVarRef, B.LastIteration, B.CalcLastIteration, B.PreCond, 02955 B.Cond, B.SeparatedCond, B.Init, B.Inc, B.Counters, B.Updates, B.Finals); 02956 } 02957 02958 StmtResult Sema::ActOnOpenMPForSimdDirective( 02959 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 02960 SourceLocation EndLoc, 02961 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 02962 BuiltLoopExprs B; 02963 // In presence of clause 'collapse', it will define the nested loops number. 02964 unsigned NestedLoopCount = 02965 CheckOpenMPLoop(OMPD_for_simd, GetCollapseNumberExpr(Clauses), AStmt, 02966 *this, *DSAStack, VarsWithImplicitDSA, B); 02967 if (NestedLoopCount == 0) 02968 return StmtError(); 02969 02970 getCurFunction()->setHasBranchProtectedScope(); 02971 return OMPForSimdDirective::Create( 02972 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, 02973 B.IterationVarRef, B.LastIteration, B.CalcLastIteration, B.PreCond, 02974 B.Cond, B.SeparatedCond, B.Init, B.Inc, B.Counters, B.Updates, B.Finals); 02975 } 02976 02977 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 02978 Stmt *AStmt, 02979 SourceLocation StartLoc, 02980 SourceLocation EndLoc) { 02981 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 02982 auto BaseStmt = AStmt; 02983 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 02984 BaseStmt = CS->getCapturedStmt(); 02985 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 02986 auto S = C->children(); 02987 if (!S) 02988 return StmtError(); 02989 // All associated statements must be '#pragma omp section' except for 02990 // the first one. 02991 for (++S; S; ++S) { 02992 auto SectionStmt = *S; 02993 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 02994 if (SectionStmt) 02995 Diag(SectionStmt->getLocStart(), 02996 diag::err_omp_sections_substmt_not_section); 02997 return StmtError(); 02998 } 02999 } 03000 } else { 03001 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 03002 return StmtError(); 03003 } 03004 03005 getCurFunction()->setHasBranchProtectedScope(); 03006 03007 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, 03008 AStmt); 03009 } 03010 03011 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 03012 SourceLocation StartLoc, 03013 SourceLocation EndLoc) { 03014 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03015 03016 getCurFunction()->setHasBranchProtectedScope(); 03017 03018 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt); 03019 } 03020 03021 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 03022 Stmt *AStmt, 03023 SourceLocation StartLoc, 03024 SourceLocation EndLoc) { 03025 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03026 03027 getCurFunction()->setHasBranchProtectedScope(); 03028 03029 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 03030 } 03031 03032 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 03033 SourceLocation StartLoc, 03034 SourceLocation EndLoc) { 03035 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03036 03037 getCurFunction()->setHasBranchProtectedScope(); 03038 03039 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 03040 } 03041 03042 StmtResult 03043 Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, 03044 Stmt *AStmt, SourceLocation StartLoc, 03045 SourceLocation EndLoc) { 03046 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03047 03048 getCurFunction()->setHasBranchProtectedScope(); 03049 03050 return OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 03051 AStmt); 03052 } 03053 03054 StmtResult Sema::ActOnOpenMPParallelForDirective( 03055 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 03056 SourceLocation EndLoc, 03057 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 03058 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03059 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 03060 // 1.2.2 OpenMP Language Terminology 03061 // Structured block - An executable statement with a single entry at the 03062 // top and a single exit at the bottom. 03063 // The point of exit cannot be a branch out of the structured block. 03064 // longjmp() and throw() must not violate the entry/exit criteria. 03065 CS->getCapturedDecl()->setNothrow(); 03066 03067 BuiltLoopExprs B; 03068 // In presence of clause 'collapse', it will define the nested loops number. 03069 unsigned NestedLoopCount = 03070 CheckOpenMPLoop(OMPD_parallel_for, GetCollapseNumberExpr(Clauses), AStmt, 03071 *this, *DSAStack, VarsWithImplicitDSA, B); 03072 if (NestedLoopCount == 0) 03073 return StmtError(); 03074 03075 assert((CurContext->isDependentContext() || B.builtAll()) && 03076 "omp parallel for loop exprs were not built"); 03077 03078 getCurFunction()->setHasBranchProtectedScope(); 03079 return OMPParallelForDirective::Create( 03080 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, 03081 B.IterationVarRef, B.LastIteration, B.CalcLastIteration, B.PreCond, 03082 B.Cond, B.SeparatedCond, B.Init, B.Inc, B.Counters, B.Updates, B.Finals); 03083 } 03084 03085 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 03086 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 03087 SourceLocation EndLoc, 03088 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 03089 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03090 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 03091 // 1.2.2 OpenMP Language Terminology 03092 // Structured block - An executable statement with a single entry at the 03093 // top and a single exit at the bottom. 03094 // The point of exit cannot be a branch out of the structured block. 03095 // longjmp() and throw() must not violate the entry/exit criteria. 03096 CS->getCapturedDecl()->setNothrow(); 03097 03098 BuiltLoopExprs B; 03099 // In presence of clause 'collapse', it will define the nested loops number. 03100 unsigned NestedLoopCount = 03101 CheckOpenMPLoop(OMPD_parallel_for_simd, GetCollapseNumberExpr(Clauses), 03102 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 03103 if (NestedLoopCount == 0) 03104 return StmtError(); 03105 03106 getCurFunction()->setHasBranchProtectedScope(); 03107 return OMPParallelForSimdDirective::Create( 03108 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, 03109 B.IterationVarRef, B.LastIteration, B.CalcLastIteration, B.PreCond, 03110 B.Cond, B.SeparatedCond, B.Init, B.Inc, B.Counters, B.Updates, B.Finals); 03111 } 03112 03113 StmtResult 03114 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 03115 Stmt *AStmt, SourceLocation StartLoc, 03116 SourceLocation EndLoc) { 03117 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03118 auto BaseStmt = AStmt; 03119 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 03120 BaseStmt = CS->getCapturedStmt(); 03121 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 03122 auto S = C->children(); 03123 if (!S) 03124 return StmtError(); 03125 // All associated statements must be '#pragma omp section' except for 03126 // the first one. 03127 for (++S; S; ++S) { 03128 auto SectionStmt = *S; 03129 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 03130 if (SectionStmt) 03131 Diag(SectionStmt->getLocStart(), 03132 diag::err_omp_parallel_sections_substmt_not_section); 03133 return StmtError(); 03134 } 03135 } 03136 } else { 03137 Diag(AStmt->getLocStart(), 03138 diag::err_omp_parallel_sections_not_compound_stmt); 03139 return StmtError(); 03140 } 03141 03142 getCurFunction()->setHasBranchProtectedScope(); 03143 03144 return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc, 03145 Clauses, AStmt); 03146 } 03147 03148 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 03149 Stmt *AStmt, SourceLocation StartLoc, 03150 SourceLocation EndLoc) { 03151 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03152 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 03153 // 1.2.2 OpenMP Language Terminology 03154 // Structured block - An executable statement with a single entry at the 03155 // top and a single exit at the bottom. 03156 // The point of exit cannot be a branch out of the structured block. 03157 // longjmp() and throw() must not violate the entry/exit criteria. 03158 CS->getCapturedDecl()->setNothrow(); 03159 03160 getCurFunction()->setHasBranchProtectedScope(); 03161 03162 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 03163 } 03164 03165 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 03166 SourceLocation EndLoc) { 03167 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 03168 } 03169 03170 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 03171 SourceLocation EndLoc) { 03172 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 03173 } 03174 03175 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 03176 SourceLocation EndLoc) { 03177 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 03178 } 03179 03180 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 03181 SourceLocation StartLoc, 03182 SourceLocation EndLoc) { 03183 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 03184 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 03185 } 03186 03187 StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt, 03188 SourceLocation StartLoc, 03189 SourceLocation EndLoc) { 03190 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03191 03192 getCurFunction()->setHasBranchProtectedScope(); 03193 03194 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, AStmt); 03195 } 03196 03197 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 03198 Stmt *AStmt, 03199 SourceLocation StartLoc, 03200 SourceLocation EndLoc) { 03201 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03202 auto CS = cast<CapturedStmt>(AStmt); 03203 // 1.2.2 OpenMP Language Terminology 03204 // Structured block - An executable statement with a single entry at the 03205 // top and a single exit at the bottom. 03206 // The point of exit cannot be a branch out of the structured block. 03207 // longjmp() and throw() must not violate the entry/exit criteria. 03208 // TODO further analysis of associated statements and clauses. 03209 OpenMPClauseKind AtomicKind = OMPC_unknown; 03210 SourceLocation AtomicKindLoc; 03211 for (auto *C : Clauses) { 03212 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 03213 C->getClauseKind() == OMPC_update || 03214 C->getClauseKind() == OMPC_capture) { 03215 if (AtomicKind != OMPC_unknown) { 03216 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 03217 << SourceRange(C->getLocStart(), C->getLocEnd()); 03218 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 03219 << getOpenMPClauseName(AtomicKind); 03220 } else { 03221 AtomicKind = C->getClauseKind(); 03222 AtomicKindLoc = C->getLocStart(); 03223 } 03224 } 03225 } 03226 03227 auto Body = CS->getCapturedStmt(); 03228 Expr *X = nullptr; 03229 Expr *V = nullptr; 03230 Expr *E = nullptr; 03231 // OpenMP [2.12.6, atomic Construct] 03232 // In the next expressions: 03233 // * x and v (as applicable) are both l-value expressions with scalar type. 03234 // * During the execution of an atomic region, multiple syntactic 03235 // occurrences of x must designate the same storage location. 03236 // * Neither of v and expr (as applicable) may access the storage location 03237 // designated by x. 03238 // * Neither of x and expr (as applicable) may access the storage location 03239 // designated by v. 03240 // * expr is an expression with scalar type. 03241 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 03242 // * binop, binop=, ++, and -- are not overloaded operators. 03243 // * The expression x binop expr must be numerically equivalent to x binop 03244 // (expr). This requirement is satisfied if the operators in expr have 03245 // precedence greater than binop, or by using parentheses around expr or 03246 // subexpressions of expr. 03247 // * The expression expr binop x must be numerically equivalent to (expr) 03248 // binop x. This requirement is satisfied if the operators in expr have 03249 // precedence equal to or greater than binop, or by using parentheses around 03250 // expr or subexpressions of expr. 03251 // * For forms that allow multiple occurrences of x, the number of times 03252 // that x is evaluated is unspecified. 03253 if (AtomicKind == OMPC_read) { 03254 enum { 03255 NotAnExpression, 03256 NotAnAssignmentOp, 03257 NotAScalarType, 03258 NotAnLValue, 03259 NoError 03260 } ErrorFound = NoError; 03261 SourceLocation ErrorLoc, NoteLoc; 03262 SourceRange ErrorRange, NoteRange; 03263 // If clause is read: 03264 // v = x; 03265 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 03266 auto AtomicBinOp = 03267 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 03268 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 03269 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 03270 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 03271 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 03272 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 03273 if (!X->isLValue() || !V->isLValue()) { 03274 auto NotLValueExpr = X->isLValue() ? V : X; 03275 ErrorFound = NotAnLValue; 03276 ErrorLoc = AtomicBinOp->getExprLoc(); 03277 ErrorRange = AtomicBinOp->getSourceRange(); 03278 NoteLoc = NotLValueExpr->getExprLoc(); 03279 NoteRange = NotLValueExpr->getSourceRange(); 03280 } 03281 } else if (!X->isInstantiationDependent() || 03282 !V->isInstantiationDependent()) { 03283 auto NotScalarExpr = 03284 (X->isInstantiationDependent() || X->getType()->isScalarType()) 03285 ? V 03286 : X; 03287 ErrorFound = NotAScalarType; 03288 ErrorLoc = AtomicBinOp->getExprLoc(); 03289 ErrorRange = AtomicBinOp->getSourceRange(); 03290 NoteLoc = NotScalarExpr->getExprLoc(); 03291 NoteRange = NotScalarExpr->getSourceRange(); 03292 } 03293 } else { 03294 ErrorFound = NotAnAssignmentOp; 03295 ErrorLoc = AtomicBody->getExprLoc(); 03296 ErrorRange = AtomicBody->getSourceRange(); 03297 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 03298 : AtomicBody->getExprLoc(); 03299 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 03300 : AtomicBody->getSourceRange(); 03301 } 03302 } else { 03303 ErrorFound = NotAnExpression; 03304 NoteLoc = ErrorLoc = Body->getLocStart(); 03305 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 03306 } 03307 if (ErrorFound != NoError) { 03308 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 03309 << ErrorRange; 03310 Diag(NoteLoc, diag::note_omp_atomic_read) << ErrorFound << NoteRange; 03311 return StmtError(); 03312 } else if (CurContext->isDependentContext()) 03313 V = X = nullptr; 03314 } else if (AtomicKind == OMPC_write) { 03315 if (!isa<Expr>(Body)) { 03316 Diag(Body->getLocStart(), 03317 diag::err_omp_atomic_write_not_expression_statement); 03318 return StmtError(); 03319 } 03320 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 03321 if (!isa<Expr>(Body)) { 03322 Diag(Body->getLocStart(), 03323 diag::err_omp_atomic_update_not_expression_statement) 03324 << (AtomicKind == OMPC_update); 03325 return StmtError(); 03326 } 03327 } else if (AtomicKind == OMPC_capture) { 03328 if (isa<Expr>(Body) && !isa<BinaryOperator>(Body)) { 03329 Diag(Body->getLocStart(), 03330 diag::err_omp_atomic_capture_not_expression_statement); 03331 return StmtError(); 03332 } else if (!isa<Expr>(Body) && !isa<CompoundStmt>(Body)) { 03333 Diag(Body->getLocStart(), 03334 diag::err_omp_atomic_capture_not_compound_statement); 03335 return StmtError(); 03336 } 03337 } 03338 03339 getCurFunction()->setHasBranchProtectedScope(); 03340 03341 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 03342 X, V, E); 03343 } 03344 03345 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 03346 Stmt *AStmt, 03347 SourceLocation StartLoc, 03348 SourceLocation EndLoc) { 03349 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03350 03351 // OpenMP [2.16, Nesting of Regions] 03352 // If specified, a teams construct must be contained within a target 03353 // construct. That target construct must contain no statements or directives 03354 // outside of the teams construct. 03355 if (DSAStack->hasInnerTeamsRegion()) { 03356 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 03357 bool OMPTeamsFound = true; 03358 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 03359 auto I = CS->body_begin(); 03360 while (I != CS->body_end()) { 03361 auto OED = dyn_cast<OMPExecutableDirective>(*I); 03362 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 03363 OMPTeamsFound = false; 03364 break; 03365 } 03366 ++I; 03367 } 03368 assert(I != CS->body_end() && "Not found statement"); 03369 S = *I; 03370 } 03371 if (!OMPTeamsFound) { 03372 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 03373 Diag(DSAStack->getInnerTeamsRegionLoc(), 03374 diag::note_omp_nested_teams_construct_here); 03375 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 03376 << isa<OMPExecutableDirective>(S); 03377 return StmtError(); 03378 } 03379 } 03380 03381 getCurFunction()->setHasBranchProtectedScope(); 03382 03383 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 03384 } 03385 03386 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 03387 Stmt *AStmt, SourceLocation StartLoc, 03388 SourceLocation EndLoc) { 03389 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 03390 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 03391 // 1.2.2 OpenMP Language Terminology 03392 // Structured block - An executable statement with a single entry at the 03393 // top and a single exit at the bottom. 03394 // The point of exit cannot be a branch out of the structured block. 03395 // longjmp() and throw() must not violate the entry/exit criteria. 03396 CS->getCapturedDecl()->setNothrow(); 03397 03398 getCurFunction()->setHasBranchProtectedScope(); 03399 03400 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 03401 } 03402 03403 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 03404 SourceLocation StartLoc, 03405 SourceLocation LParenLoc, 03406 SourceLocation EndLoc) { 03407 OMPClause *Res = nullptr; 03408 switch (Kind) { 03409 case OMPC_if: 03410 Res = ActOnOpenMPIfClause(Expr, StartLoc, LParenLoc, EndLoc); 03411 break; 03412 case OMPC_final: 03413 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 03414 break; 03415 case OMPC_num_threads: 03416 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 03417 break; 03418 case OMPC_safelen: 03419 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 03420 break; 03421 case OMPC_collapse: 03422 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 03423 break; 03424 case OMPC_default: 03425 case OMPC_proc_bind: 03426 case OMPC_schedule: 03427 case OMPC_private: 03428 case OMPC_firstprivate: 03429 case OMPC_lastprivate: 03430 case OMPC_shared: 03431 case OMPC_reduction: 03432 case OMPC_linear: 03433 case OMPC_aligned: 03434 case OMPC_copyin: 03435 case OMPC_copyprivate: 03436 case OMPC_ordered: 03437 case OMPC_nowait: 03438 case OMPC_untied: 03439 case OMPC_mergeable: 03440 case OMPC_threadprivate: 03441 case OMPC_flush: 03442 case OMPC_read: 03443 case OMPC_write: 03444 case OMPC_update: 03445 case OMPC_capture: 03446 case OMPC_seq_cst: 03447 case OMPC_unknown: 03448 llvm_unreachable("Clause is not allowed."); 03449 } 03450 return Res; 03451 } 03452 03453 OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, 03454 SourceLocation LParenLoc, 03455 SourceLocation EndLoc) { 03456 Expr *ValExpr = Condition; 03457 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 03458 !Condition->isInstantiationDependent() && 03459 !Condition->containsUnexpandedParameterPack()) { 03460 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 03461 Condition->getExprLoc(), Condition); 03462 if (Val.isInvalid()) 03463 return nullptr; 03464 03465 ValExpr = Val.get(); 03466 } 03467 03468 return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc); 03469 } 03470 03471 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 03472 SourceLocation StartLoc, 03473 SourceLocation LParenLoc, 03474 SourceLocation EndLoc) { 03475 Expr *ValExpr = Condition; 03476 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 03477 !Condition->isInstantiationDependent() && 03478 !Condition->containsUnexpandedParameterPack()) { 03479 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 03480 Condition->getExprLoc(), Condition); 03481 if (Val.isInvalid()) 03482 return nullptr; 03483 03484 ValExpr = Val.get(); 03485 } 03486 03487 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 03488 } 03489 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 03490 Expr *Op) { 03491 if (!Op) 03492 return ExprError(); 03493 03494 class IntConvertDiagnoser : public ICEConvertDiagnoser { 03495 public: 03496 IntConvertDiagnoser() 03497 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 03498 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 03499 QualType T) override { 03500 return S.Diag(Loc, diag::err_omp_not_integral) << T; 03501 } 03502 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 03503 QualType T) override { 03504 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 03505 } 03506 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 03507 QualType T, 03508 QualType ConvTy) override { 03509 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 03510 } 03511 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 03512 QualType ConvTy) override { 03513 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 03514 << ConvTy->isEnumeralType() << ConvTy; 03515 } 03516 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 03517 QualType T) override { 03518 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 03519 } 03520 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 03521 QualType ConvTy) override { 03522 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 03523 << ConvTy->isEnumeralType() << ConvTy; 03524 } 03525 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 03526 QualType) override { 03527 llvm_unreachable("conversion functions are permitted"); 03528 } 03529 } ConvertDiagnoser; 03530 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 03531 } 03532 03533 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 03534 SourceLocation StartLoc, 03535 SourceLocation LParenLoc, 03536 SourceLocation EndLoc) { 03537 Expr *ValExpr = NumThreads; 03538 if (!NumThreads->isValueDependent() && !NumThreads->isTypeDependent() && 03539 !NumThreads->containsUnexpandedParameterPack()) { 03540 SourceLocation NumThreadsLoc = NumThreads->getLocStart(); 03541 ExprResult Val = 03542 PerformOpenMPImplicitIntegerConversion(NumThreadsLoc, NumThreads); 03543 if (Val.isInvalid()) 03544 return nullptr; 03545 03546 ValExpr = Val.get(); 03547 03548 // OpenMP [2.5, Restrictions] 03549 // The num_threads expression must evaluate to a positive integer value. 03550 llvm::APSInt Result; 03551 if (ValExpr->isIntegerConstantExpr(Result, Context) && Result.isSigned() && 03552 !Result.isStrictlyPositive()) { 03553 Diag(NumThreadsLoc, diag::err_omp_negative_expression_in_clause) 03554 << "num_threads" << NumThreads->getSourceRange(); 03555 return nullptr; 03556 } 03557 } 03558 03559 return new (Context) 03560 OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 03561 } 03562 03563 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 03564 OpenMPClauseKind CKind) { 03565 if (!E) 03566 return ExprError(); 03567 if (E->isValueDependent() || E->isTypeDependent() || 03568 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 03569 return E; 03570 llvm::APSInt Result; 03571 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 03572 if (ICE.isInvalid()) 03573 return ExprError(); 03574 if (!Result.isStrictlyPositive()) { 03575 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 03576 << getOpenMPClauseName(CKind) << E->getSourceRange(); 03577 return ExprError(); 03578 } 03579 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 03580 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 03581 << E->getSourceRange(); 03582 return ExprError(); 03583 } 03584 return ICE; 03585 } 03586 03587 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 03588 SourceLocation LParenLoc, 03589 SourceLocation EndLoc) { 03590 // OpenMP [2.8.1, simd construct, Description] 03591 // The parameter of the safelen clause must be a constant 03592 // positive integer expression. 03593 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 03594 if (Safelen.isInvalid()) 03595 return nullptr; 03596 return new (Context) 03597 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 03598 } 03599 03600 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 03601 SourceLocation StartLoc, 03602 SourceLocation LParenLoc, 03603 SourceLocation EndLoc) { 03604 // OpenMP [2.7.1, loop construct, Description] 03605 // OpenMP [2.8.1, simd construct, Description] 03606 // OpenMP [2.9.6, distribute construct, Description] 03607 // The parameter of the collapse clause must be a constant 03608 // positive integer expression. 03609 ExprResult NumForLoopsResult = 03610 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 03611 if (NumForLoopsResult.isInvalid()) 03612 return nullptr; 03613 return new (Context) 03614 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 03615 } 03616 03617 OMPClause *Sema::ActOnOpenMPSimpleClause( 03618 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 03619 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 03620 OMPClause *Res = nullptr; 03621 switch (Kind) { 03622 case OMPC_default: 03623 Res = 03624 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 03625 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 03626 break; 03627 case OMPC_proc_bind: 03628 Res = ActOnOpenMPProcBindClause( 03629 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 03630 LParenLoc, EndLoc); 03631 break; 03632 case OMPC_if: 03633 case OMPC_final: 03634 case OMPC_num_threads: 03635 case OMPC_safelen: 03636 case OMPC_collapse: 03637 case OMPC_schedule: 03638 case OMPC_private: 03639 case OMPC_firstprivate: 03640 case OMPC_lastprivate: 03641 case OMPC_shared: 03642 case OMPC_reduction: 03643 case OMPC_linear: 03644 case OMPC_aligned: 03645 case OMPC_copyin: 03646 case OMPC_copyprivate: 03647 case OMPC_ordered: 03648 case OMPC_nowait: 03649 case OMPC_untied: 03650 case OMPC_mergeable: 03651 case OMPC_threadprivate: 03652 case OMPC_flush: 03653 case OMPC_read: 03654 case OMPC_write: 03655 case OMPC_update: 03656 case OMPC_capture: 03657 case OMPC_seq_cst: 03658 case OMPC_unknown: 03659 llvm_unreachable("Clause is not allowed."); 03660 } 03661 return Res; 03662 } 03663 03664 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 03665 SourceLocation KindKwLoc, 03666 SourceLocation StartLoc, 03667 SourceLocation LParenLoc, 03668 SourceLocation EndLoc) { 03669 if (Kind == OMPC_DEFAULT_unknown) { 03670 std::string Values; 03671 static_assert(OMPC_DEFAULT_unknown > 0, 03672 "OMPC_DEFAULT_unknown not greater than 0"); 03673 std::string Sep(", "); 03674 for (unsigned i = 0; i < OMPC_DEFAULT_unknown; ++i) { 03675 Values += "'"; 03676 Values += getOpenMPSimpleClauseTypeName(OMPC_default, i); 03677 Values += "'"; 03678 switch (i) { 03679 case OMPC_DEFAULT_unknown - 2: 03680 Values += " or "; 03681 break; 03682 case OMPC_DEFAULT_unknown - 1: 03683 break; 03684 default: 03685 Values += Sep; 03686 break; 03687 } 03688 } 03689 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 03690 << Values << getOpenMPClauseName(OMPC_default); 03691 return nullptr; 03692 } 03693 switch (Kind) { 03694 case OMPC_DEFAULT_none: 03695 DSAStack->setDefaultDSANone(KindKwLoc); 03696 break; 03697 case OMPC_DEFAULT_shared: 03698 DSAStack->setDefaultDSAShared(KindKwLoc); 03699 break; 03700 case OMPC_DEFAULT_unknown: 03701 llvm_unreachable("Clause kind is not allowed."); 03702 break; 03703 } 03704 return new (Context) 03705 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 03706 } 03707 03708 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 03709 SourceLocation KindKwLoc, 03710 SourceLocation StartLoc, 03711 SourceLocation LParenLoc, 03712 SourceLocation EndLoc) { 03713 if (Kind == OMPC_PROC_BIND_unknown) { 03714 std::string Values; 03715 std::string Sep(", "); 03716 for (unsigned i = 0; i < OMPC_PROC_BIND_unknown; ++i) { 03717 Values += "'"; 03718 Values += getOpenMPSimpleClauseTypeName(OMPC_proc_bind, i); 03719 Values += "'"; 03720 switch (i) { 03721 case OMPC_PROC_BIND_unknown - 2: 03722 Values += " or "; 03723 break; 03724 case OMPC_PROC_BIND_unknown - 1: 03725 break; 03726 default: 03727 Values += Sep; 03728 break; 03729 } 03730 } 03731 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 03732 << Values << getOpenMPClauseName(OMPC_proc_bind); 03733 return nullptr; 03734 } 03735 return new (Context) 03736 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 03737 } 03738 03739 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 03740 OpenMPClauseKind Kind, unsigned Argument, Expr *Expr, 03741 SourceLocation StartLoc, SourceLocation LParenLoc, 03742 SourceLocation ArgumentLoc, SourceLocation CommaLoc, 03743 SourceLocation EndLoc) { 03744 OMPClause *Res = nullptr; 03745 switch (Kind) { 03746 case OMPC_schedule: 03747 Res = ActOnOpenMPScheduleClause( 03748 static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc, 03749 LParenLoc, ArgumentLoc, CommaLoc, EndLoc); 03750 break; 03751 case OMPC_if: 03752 case OMPC_final: 03753 case OMPC_num_threads: 03754 case OMPC_safelen: 03755 case OMPC_collapse: 03756 case OMPC_default: 03757 case OMPC_proc_bind: 03758 case OMPC_private: 03759 case OMPC_firstprivate: 03760 case OMPC_lastprivate: 03761 case OMPC_shared: 03762 case OMPC_reduction: 03763 case OMPC_linear: 03764 case OMPC_aligned: 03765 case OMPC_copyin: 03766 case OMPC_copyprivate: 03767 case OMPC_ordered: 03768 case OMPC_nowait: 03769 case OMPC_untied: 03770 case OMPC_mergeable: 03771 case OMPC_threadprivate: 03772 case OMPC_flush: 03773 case OMPC_read: 03774 case OMPC_write: 03775 case OMPC_update: 03776 case OMPC_capture: 03777 case OMPC_seq_cst: 03778 case OMPC_unknown: 03779 llvm_unreachable("Clause is not allowed."); 03780 } 03781 return Res; 03782 } 03783 03784 OMPClause *Sema::ActOnOpenMPScheduleClause( 03785 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 03786 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 03787 SourceLocation EndLoc) { 03788 if (Kind == OMPC_SCHEDULE_unknown) { 03789 std::string Values; 03790 std::string Sep(", "); 03791 for (unsigned i = 0; i < OMPC_SCHEDULE_unknown; ++i) { 03792 Values += "'"; 03793 Values += getOpenMPSimpleClauseTypeName(OMPC_schedule, i); 03794 Values += "'"; 03795 switch (i) { 03796 case OMPC_SCHEDULE_unknown - 2: 03797 Values += " or "; 03798 break; 03799 case OMPC_SCHEDULE_unknown - 1: 03800 break; 03801 default: 03802 Values += Sep; 03803 break; 03804 } 03805 } 03806 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 03807 << Values << getOpenMPClauseName(OMPC_schedule); 03808 return nullptr; 03809 } 03810 Expr *ValExpr = ChunkSize; 03811 if (ChunkSize) { 03812 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 03813 !ChunkSize->isInstantiationDependent() && 03814 !ChunkSize->containsUnexpandedParameterPack()) { 03815 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 03816 ExprResult Val = 03817 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 03818 if (Val.isInvalid()) 03819 return nullptr; 03820 03821 ValExpr = Val.get(); 03822 03823 // OpenMP [2.7.1, Restrictions] 03824 // chunk_size must be a loop invariant integer expression with a positive 03825 // value. 03826 llvm::APSInt Result; 03827 if (ValExpr->isIntegerConstantExpr(Result, Context) && 03828 Result.isSigned() && !Result.isStrictlyPositive()) { 03829 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 03830 << "schedule" << ChunkSize->getSourceRange(); 03831 return nullptr; 03832 } 03833 } 03834 } 03835 03836 return new (Context) OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, 03837 EndLoc, Kind, ValExpr); 03838 } 03839 03840 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 03841 SourceLocation StartLoc, 03842 SourceLocation EndLoc) { 03843 OMPClause *Res = nullptr; 03844 switch (Kind) { 03845 case OMPC_ordered: 03846 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 03847 break; 03848 case OMPC_nowait: 03849 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 03850 break; 03851 case OMPC_untied: 03852 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 03853 break; 03854 case OMPC_mergeable: 03855 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 03856 break; 03857 case OMPC_read: 03858 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 03859 break; 03860 case OMPC_write: 03861 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 03862 break; 03863 case OMPC_update: 03864 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 03865 break; 03866 case OMPC_capture: 03867 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 03868 break; 03869 case OMPC_seq_cst: 03870 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 03871 break; 03872 case OMPC_if: 03873 case OMPC_final: 03874 case OMPC_num_threads: 03875 case OMPC_safelen: 03876 case OMPC_collapse: 03877 case OMPC_schedule: 03878 case OMPC_private: 03879 case OMPC_firstprivate: 03880 case OMPC_lastprivate: 03881 case OMPC_shared: 03882 case OMPC_reduction: 03883 case OMPC_linear: 03884 case OMPC_aligned: 03885 case OMPC_copyin: 03886 case OMPC_copyprivate: 03887 case OMPC_default: 03888 case OMPC_proc_bind: 03889 case OMPC_threadprivate: 03890 case OMPC_flush: 03891 case OMPC_unknown: 03892 llvm_unreachable("Clause is not allowed."); 03893 } 03894 return Res; 03895 } 03896 03897 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 03898 SourceLocation EndLoc) { 03899 DSAStack->setOrderedRegion(); 03900 return new (Context) OMPOrderedClause(StartLoc, EndLoc); 03901 } 03902 03903 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 03904 SourceLocation EndLoc) { 03905 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 03906 } 03907 03908 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 03909 SourceLocation EndLoc) { 03910 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 03911 } 03912 03913 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 03914 SourceLocation EndLoc) { 03915 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 03916 } 03917 03918 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 03919 SourceLocation EndLoc) { 03920 return new (Context) OMPReadClause(StartLoc, EndLoc); 03921 } 03922 03923 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 03924 SourceLocation EndLoc) { 03925 return new (Context) OMPWriteClause(StartLoc, EndLoc); 03926 } 03927 03928 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 03929 SourceLocation EndLoc) { 03930 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 03931 } 03932 03933 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 03934 SourceLocation EndLoc) { 03935 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 03936 } 03937 03938 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 03939 SourceLocation EndLoc) { 03940 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 03941 } 03942 03943 OMPClause *Sema::ActOnOpenMPVarListClause( 03944 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 03945 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 03946 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 03947 const DeclarationNameInfo &ReductionId) { 03948 OMPClause *Res = nullptr; 03949 switch (Kind) { 03950 case OMPC_private: 03951 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 03952 break; 03953 case OMPC_firstprivate: 03954 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 03955 break; 03956 case OMPC_lastprivate: 03957 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 03958 break; 03959 case OMPC_shared: 03960 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 03961 break; 03962 case OMPC_reduction: 03963 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 03964 EndLoc, ReductionIdScopeSpec, ReductionId); 03965 break; 03966 case OMPC_linear: 03967 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 03968 ColonLoc, EndLoc); 03969 break; 03970 case OMPC_aligned: 03971 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 03972 ColonLoc, EndLoc); 03973 break; 03974 case OMPC_copyin: 03975 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 03976 break; 03977 case OMPC_copyprivate: 03978 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 03979 break; 03980 case OMPC_flush: 03981 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 03982 break; 03983 case OMPC_if: 03984 case OMPC_final: 03985 case OMPC_num_threads: 03986 case OMPC_safelen: 03987 case OMPC_collapse: 03988 case OMPC_default: 03989 case OMPC_proc_bind: 03990 case OMPC_schedule: 03991 case OMPC_ordered: 03992 case OMPC_nowait: 03993 case OMPC_untied: 03994 case OMPC_mergeable: 03995 case OMPC_threadprivate: 03996 case OMPC_read: 03997 case OMPC_write: 03998 case OMPC_update: 03999 case OMPC_capture: 04000 case OMPC_seq_cst: 04001 case OMPC_unknown: 04002 llvm_unreachable("Clause is not allowed."); 04003 } 04004 return Res; 04005 } 04006 04007 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 04008 SourceLocation StartLoc, 04009 SourceLocation LParenLoc, 04010 SourceLocation EndLoc) { 04011 SmallVector<Expr *, 8> Vars; 04012 SmallVector<Expr *, 8> PrivateCopies; 04013 for (auto &RefExpr : VarList) { 04014 assert(RefExpr && "NULL expr in OpenMP private clause."); 04015 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 04016 // It will be analyzed later. 04017 Vars.push_back(RefExpr); 04018 PrivateCopies.push_back(nullptr); 04019 continue; 04020 } 04021 04022 SourceLocation ELoc = RefExpr->getExprLoc(); 04023 // OpenMP [2.1, C/C++] 04024 // A list item is a variable name. 04025 // OpenMP [2.9.3.3, Restrictions, p.1] 04026 // A variable that is part of another variable (as an array or 04027 // structure element) cannot appear in a private clause. 04028 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 04029 if (!DE || !isa<VarDecl>(DE->getDecl())) { 04030 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 04031 continue; 04032 } 04033 Decl *D = DE->getDecl(); 04034 VarDecl *VD = cast<VarDecl>(D); 04035 04036 QualType Type = VD->getType(); 04037 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 04038 // It will be analyzed later. 04039 Vars.push_back(DE); 04040 PrivateCopies.push_back(nullptr); 04041 continue; 04042 } 04043 04044 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 04045 // A variable that appears in a private clause must not have an incomplete 04046 // type or a reference type. 04047 if (RequireCompleteType(ELoc, Type, 04048 diag::err_omp_private_incomplete_type)) { 04049 continue; 04050 } 04051 if (Type->isReferenceType()) { 04052 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 04053 << getOpenMPClauseName(OMPC_private) << Type; 04054 bool IsDecl = 04055 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 04056 Diag(VD->getLocation(), 04057 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04058 << VD; 04059 continue; 04060 } 04061 04062 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 04063 // A variable of class type (or array thereof) that appears in a private 04064 // clause requires an accessible, unambiguous default constructor for the 04065 // class type. 04066 while (Type->isArrayType()) { 04067 Type = cast<ArrayType>(Type.getTypePtr())->getElementType(); 04068 } 04069 04070 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 04071 // in a Construct] 04072 // Variables with the predetermined data-sharing attributes may not be 04073 // listed in data-sharing attributes clauses, except for the cases 04074 // listed below. For these exceptions only, listing a predetermined 04075 // variable in a data-sharing attribute clause is allowed and overrides 04076 // the variable's predetermined data-sharing attributes. 04077 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 04078 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 04079 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 04080 << getOpenMPClauseName(OMPC_private); 04081 ReportOriginalDSA(*this, DSAStack, VD, DVar); 04082 continue; 04083 } 04084 04085 // Generate helper private variable and initialize it with the default 04086 // value. The address of the original variable is replaced by the address of 04087 // the new private variable in CodeGen. This new variable is not added to 04088 // IdResolver, so the code in the OpenMP region uses original variable for 04089 // proper diagnostics. 04090 auto VDPrivate = 04091 VarDecl::Create(Context, CurContext, DE->getLocStart(), 04092 DE->getExprLoc(), VD->getIdentifier(), VD->getType(), 04093 VD->getTypeSourceInfo(), /*S*/ SC_Auto); 04094 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto*/ false); 04095 if (VDPrivate->isInvalidDecl()) 04096 continue; 04097 CurContext->addDecl(VDPrivate); 04098 auto VDPrivateRefExpr = DeclRefExpr::Create( 04099 Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), 04100 /*TemplateKWLoc*/ SourceLocation(), VDPrivate, 04101 /*isEnclosingLocal*/ false, /*NameLoc*/ SourceLocation(), DE->getType(), 04102 /*VK*/ VK_LValue); 04103 04104 DSAStack->addDSA(VD, DE, OMPC_private); 04105 Vars.push_back(DE); 04106 PrivateCopies.push_back(VDPrivateRefExpr); 04107 } 04108 04109 if (Vars.empty()) 04110 return nullptr; 04111 04112 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 04113 PrivateCopies); 04114 } 04115 04116 namespace { 04117 class DiagsUninitializedSeveretyRAII { 04118 private: 04119 DiagnosticsEngine &Diags; 04120 SourceLocation SavedLoc; 04121 bool IsIgnored; 04122 04123 public: 04124 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 04125 bool IsIgnored) 04126 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 04127 if (!IsIgnored) { 04128 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 04129 /*Map*/ diag::Severity::Ignored, Loc); 04130 } 04131 } 04132 ~DiagsUninitializedSeveretyRAII() { 04133 if (!IsIgnored) 04134 Diags.popMappings(SavedLoc); 04135 } 04136 }; 04137 } 04138 04139 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 04140 SourceLocation StartLoc, 04141 SourceLocation LParenLoc, 04142 SourceLocation EndLoc) { 04143 SmallVector<Expr *, 8> Vars; 04144 SmallVector<Expr *, 8> PrivateCopies; 04145 SmallVector<Expr *, 8> Inits; 04146 bool IsImplicitClause = 04147 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 04148 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 04149 04150 for (auto &RefExpr : VarList) { 04151 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 04152 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 04153 // It will be analyzed later. 04154 Vars.push_back(RefExpr); 04155 PrivateCopies.push_back(nullptr); 04156 Inits.push_back(nullptr); 04157 continue; 04158 } 04159 04160 SourceLocation ELoc = 04161 IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc(); 04162 // OpenMP [2.1, C/C++] 04163 // A list item is a variable name. 04164 // OpenMP [2.9.3.3, Restrictions, p.1] 04165 // A variable that is part of another variable (as an array or 04166 // structure element) cannot appear in a private clause. 04167 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 04168 if (!DE || !isa<VarDecl>(DE->getDecl())) { 04169 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 04170 continue; 04171 } 04172 Decl *D = DE->getDecl(); 04173 VarDecl *VD = cast<VarDecl>(D); 04174 04175 QualType Type = VD->getType(); 04176 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 04177 // It will be analyzed later. 04178 Vars.push_back(DE); 04179 PrivateCopies.push_back(nullptr); 04180 Inits.push_back(nullptr); 04181 continue; 04182 } 04183 04184 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 04185 // A variable that appears in a private clause must not have an incomplete 04186 // type or a reference type. 04187 if (RequireCompleteType(ELoc, Type, 04188 diag::err_omp_firstprivate_incomplete_type)) { 04189 continue; 04190 } 04191 if (Type->isReferenceType()) { 04192 if (IsImplicitClause) { 04193 Diag(ImplicitClauseLoc, 04194 diag::err_omp_task_predetermined_firstprivate_ref_type_arg) 04195 << Type; 04196 Diag(RefExpr->getExprLoc(), diag::note_used_here); 04197 } else { 04198 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 04199 << getOpenMPClauseName(OMPC_firstprivate) << Type; 04200 } 04201 bool IsDecl = 04202 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 04203 Diag(VD->getLocation(), 04204 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04205 << VD; 04206 continue; 04207 } 04208 04209 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 04210 // A variable of class type (or array thereof) that appears in a private 04211 // clause requires an accessible, unambiguous copy constructor for the 04212 // class type. 04213 Type = Context.getBaseElementType(Type); 04214 04215 // If an implicit firstprivate variable found it was checked already. 04216 if (!IsImplicitClause) { 04217 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 04218 Type = Type.getNonReferenceType().getCanonicalType(); 04219 bool IsConstant = Type.isConstant(Context); 04220 Type = Context.getBaseElementType(Type); 04221 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 04222 // A list item that specifies a given variable may not appear in more 04223 // than one clause on the same directive, except that a variable may be 04224 // specified in both firstprivate and lastprivate clauses. 04225 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 04226 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { 04227 Diag(ELoc, diag::err_omp_wrong_dsa) 04228 << getOpenMPClauseName(DVar.CKind) 04229 << getOpenMPClauseName(OMPC_firstprivate); 04230 ReportOriginalDSA(*this, DSAStack, VD, DVar); 04231 continue; 04232 } 04233 04234 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 04235 // in a Construct] 04236 // Variables with the predetermined data-sharing attributes may not be 04237 // listed in data-sharing attributes clauses, except for the cases 04238 // listed below. For these exceptions only, listing a predetermined 04239 // variable in a data-sharing attribute clause is allowed and overrides 04240 // the variable's predetermined data-sharing attributes. 04241 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 04242 // in a Construct, C/C++, p.2] 04243 // Variables with const-qualified type having no mutable member may be 04244 // listed in a firstprivate clause, even if they are static data members. 04245 if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr && 04246 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 04247 Diag(ELoc, diag::err_omp_wrong_dsa) 04248 << getOpenMPClauseName(DVar.CKind) 04249 << getOpenMPClauseName(OMPC_firstprivate); 04250 ReportOriginalDSA(*this, DSAStack, VD, DVar); 04251 continue; 04252 } 04253 04254 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 04255 // OpenMP [2.9.3.4, Restrictions, p.2] 04256 // A list item that is private within a parallel region must not appear 04257 // in a firstprivate clause on a worksharing construct if any of the 04258 // worksharing regions arising from the worksharing construct ever bind 04259 // to any of the parallel regions arising from the parallel construct. 04260 if (isOpenMPWorksharingDirective(CurrDir) && 04261 !isOpenMPParallelDirective(CurrDir)) { 04262 DVar = DSAStack->getImplicitDSA(VD, true); 04263 if (DVar.CKind != OMPC_shared && 04264 (isOpenMPParallelDirective(DVar.DKind) || 04265 DVar.DKind == OMPD_unknown)) { 04266 Diag(ELoc, diag::err_omp_required_access) 04267 << getOpenMPClauseName(OMPC_firstprivate) 04268 << getOpenMPClauseName(OMPC_shared); 04269 ReportOriginalDSA(*this, DSAStack, VD, DVar); 04270 continue; 04271 } 04272 } 04273 // OpenMP [2.9.3.4, Restrictions, p.3] 04274 // A list item that appears in a reduction clause of a parallel construct 04275 // must not appear in a firstprivate clause on a worksharing or task 04276 // construct if any of the worksharing or task regions arising from the 04277 // worksharing or task construct ever bind to any of the parallel regions 04278 // arising from the parallel construct. 04279 // OpenMP [2.9.3.4, Restrictions, p.4] 04280 // A list item that appears in a reduction clause in worksharing 04281 // construct must not appear in a firstprivate clause in a task construct 04282 // encountered during execution of any of the worksharing regions arising 04283 // from the worksharing construct. 04284 if (CurrDir == OMPD_task) { 04285 DVar = 04286 DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction), 04287 [](OpenMPDirectiveKind K) -> bool { 04288 return isOpenMPParallelDirective(K) || 04289 isOpenMPWorksharingDirective(K); 04290 }, 04291 false); 04292 if (DVar.CKind == OMPC_reduction && 04293 (isOpenMPParallelDirective(DVar.DKind) || 04294 isOpenMPWorksharingDirective(DVar.DKind))) { 04295 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 04296 << getOpenMPDirectiveName(DVar.DKind); 04297 ReportOriginalDSA(*this, DSAStack, VD, DVar); 04298 continue; 04299 } 04300 } 04301 } 04302 04303 Type = Type.getUnqualifiedType(); 04304 auto VDPrivate = VarDecl::Create(Context, CurContext, DE->getLocStart(), 04305 ELoc, VD->getIdentifier(), VD->getType(), 04306 VD->getTypeSourceInfo(), /*S*/ SC_Auto); 04307 // Generate helper private variable and initialize it with the value of the 04308 // original variable. The address of the original variable is replaced by 04309 // the address of the new private variable in the CodeGen. This new variable 04310 // is not added to IdResolver, so the code in the OpenMP region uses 04311 // original variable for proper diagnostics and variable capturing. 04312 Expr *VDInitRefExpr = nullptr; 04313 // For arrays generate initializer for single element and replace it by the 04314 // original array element in CodeGen. 04315 if (DE->getType()->isArrayType()) { 04316 auto VDInit = VarDecl::Create(Context, CurContext, DE->getLocStart(), 04317 ELoc, VD->getIdentifier(), Type, 04318 VD->getTypeSourceInfo(), /*S*/ SC_Auto); 04319 CurContext->addHiddenDecl(VDInit); 04320 VDInitRefExpr = DeclRefExpr::Create( 04321 Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), 04322 /*TemplateKWLoc*/ SourceLocation(), VDInit, 04323 /*isEnclosingLocal*/ false, ELoc, Type, 04324 /*VK*/ VK_LValue); 04325 VDInit->setIsUsed(); 04326 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 04327 InitializedEntity Entity = InitializedEntity::InitializeVariable(VDInit); 04328 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 04329 04330 InitializationSequence InitSeq(*this, Entity, Kind, Init); 04331 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 04332 if (Result.isInvalid()) 04333 VDPrivate->setInvalidDecl(); 04334 else 04335 VDPrivate->setInit(Result.getAs<Expr>()); 04336 } else { 04337 AddInitializerToDecl(VDPrivate, DefaultLvalueConversion(DE).get(), 04338 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 04339 } 04340 if (VDPrivate->isInvalidDecl()) { 04341 if (IsImplicitClause) { 04342 Diag(DE->getExprLoc(), 04343 diag::note_omp_task_predetermined_firstprivate_here); 04344 } 04345 continue; 04346 } 04347 CurContext->addDecl(VDPrivate); 04348 auto VDPrivateRefExpr = DeclRefExpr::Create( 04349 Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), 04350 /*TemplateKWLoc*/ SourceLocation(), VDPrivate, 04351 /*isEnclosingLocal*/ false, DE->getLocStart(), DE->getType(), 04352 /*VK*/ VK_LValue); 04353 DSAStack->addDSA(VD, DE, OMPC_firstprivate); 04354 Vars.push_back(DE); 04355 PrivateCopies.push_back(VDPrivateRefExpr); 04356 Inits.push_back(VDInitRefExpr); 04357 } 04358 04359 if (Vars.empty()) 04360 return nullptr; 04361 04362 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 04363 Vars, PrivateCopies, Inits); 04364 } 04365 04366 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 04367 SourceLocation StartLoc, 04368 SourceLocation LParenLoc, 04369 SourceLocation EndLoc) { 04370 SmallVector<Expr *, 8> Vars; 04371 for (auto &RefExpr : VarList) { 04372 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 04373 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 04374 // It will be analyzed later. 04375 Vars.push_back(RefExpr); 04376 continue; 04377 } 04378 04379 SourceLocation ELoc = RefExpr->getExprLoc(); 04380 // OpenMP [2.1, C/C++] 04381 // A list item is a variable name. 04382 // OpenMP [2.14.3.5, Restrictions, p.1] 04383 // A variable that is part of another variable (as an array or structure 04384 // element) cannot appear in a lastprivate clause. 04385 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 04386 if (!DE || !isa<VarDecl>(DE->getDecl())) { 04387 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 04388 continue; 04389 } 04390 Decl *D = DE->getDecl(); 04391 VarDecl *VD = cast<VarDecl>(D); 04392 04393 QualType Type = VD->getType(); 04394 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 04395 // It will be analyzed later. 04396 Vars.push_back(DE); 04397 continue; 04398 } 04399 04400 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 04401 // A variable that appears in a lastprivate clause must not have an 04402 // incomplete type or a reference type. 04403 if (RequireCompleteType(ELoc, Type, 04404 diag::err_omp_lastprivate_incomplete_type)) { 04405 continue; 04406 } 04407 if (Type->isReferenceType()) { 04408 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 04409 << getOpenMPClauseName(OMPC_lastprivate) << Type; 04410 bool IsDecl = 04411 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 04412 Diag(VD->getLocation(), 04413 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04414 << VD; 04415 continue; 04416 } 04417 04418 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 04419 // in a Construct] 04420 // Variables with the predetermined data-sharing attributes may not be 04421 // listed in data-sharing attributes clauses, except for the cases 04422 // listed below. 04423 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 04424 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 04425 DVar.CKind != OMPC_firstprivate && 04426 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 04427 Diag(ELoc, diag::err_omp_wrong_dsa) 04428 << getOpenMPClauseName(DVar.CKind) 04429 << getOpenMPClauseName(OMPC_lastprivate); 04430 ReportOriginalDSA(*this, DSAStack, VD, DVar); 04431 continue; 04432 } 04433 04434 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 04435 // OpenMP [2.14.3.5, Restrictions, p.2] 04436 // A list item that is private within a parallel region, or that appears in 04437 // the reduction clause of a parallel construct, must not appear in a 04438 // lastprivate clause on a worksharing construct if any of the corresponding 04439 // worksharing regions ever binds to any of the corresponding parallel 04440 // regions. 04441 if (isOpenMPWorksharingDirective(CurrDir) && 04442 !isOpenMPParallelDirective(CurrDir)) { 04443 DVar = DSAStack->getImplicitDSA(VD, true); 04444 if (DVar.CKind != OMPC_shared) { 04445 Diag(ELoc, diag::err_omp_required_access) 04446 << getOpenMPClauseName(OMPC_lastprivate) 04447 << getOpenMPClauseName(OMPC_shared); 04448 ReportOriginalDSA(*this, DSAStack, VD, DVar); 04449 continue; 04450 } 04451 } 04452 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 04453 // A variable of class type (or array thereof) that appears in a 04454 // lastprivate clause requires an accessible, unambiguous default 04455 // constructor for the class type, unless the list item is also specified 04456 // in a firstprivate clause. 04457 // A variable of class type (or array thereof) that appears in a 04458 // lastprivate clause requires an accessible, unambiguous copy assignment 04459 // operator for the class type. 04460 while (Type.getNonReferenceType()->isArrayType()) 04461 Type = cast<ArrayType>(Type.getNonReferenceType().getTypePtr()) 04462 ->getElementType(); 04463 CXXRecordDecl *RD = getLangOpts().CPlusPlus 04464 ? Type.getNonReferenceType()->getAsCXXRecordDecl() 04465 : nullptr; 04466 // FIXME This code must be replaced by actual copying and destructing of the 04467 // lastprivate variable. 04468 if (RD) { 04469 CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0); 04470 DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess()); 04471 if (MD) { 04472 if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible || 04473 MD->isDeleted()) { 04474 Diag(ELoc, diag::err_omp_required_method) 04475 << getOpenMPClauseName(OMPC_lastprivate) << 2; 04476 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 04477 VarDecl::DeclarationOnly; 04478 Diag(VD->getLocation(), 04479 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04480 << VD; 04481 Diag(RD->getLocation(), diag::note_previous_decl) << RD; 04482 continue; 04483 } 04484 MarkFunctionReferenced(ELoc, MD); 04485 DiagnoseUseOfDecl(MD, ELoc); 04486 } 04487 04488 CXXDestructorDecl *DD = RD->getDestructor(); 04489 if (DD) { 04490 PartialDiagnostic PD = 04491 PartialDiagnostic(PartialDiagnostic::NullDiagnostic()); 04492 if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible || 04493 DD->isDeleted()) { 04494 Diag(ELoc, diag::err_omp_required_method) 04495 << getOpenMPClauseName(OMPC_lastprivate) << 4; 04496 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 04497 VarDecl::DeclarationOnly; 04498 Diag(VD->getLocation(), 04499 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04500 << VD; 04501 Diag(RD->getLocation(), diag::note_previous_decl) << RD; 04502 continue; 04503 } 04504 MarkFunctionReferenced(ELoc, DD); 04505 DiagnoseUseOfDecl(DD, ELoc); 04506 } 04507 } 04508 04509 if (DVar.CKind != OMPC_firstprivate) 04510 DSAStack->addDSA(VD, DE, OMPC_lastprivate); 04511 Vars.push_back(DE); 04512 } 04513 04514 if (Vars.empty()) 04515 return nullptr; 04516 04517 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 04518 Vars); 04519 } 04520 04521 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 04522 SourceLocation StartLoc, 04523 SourceLocation LParenLoc, 04524 SourceLocation EndLoc) { 04525 SmallVector<Expr *, 8> Vars; 04526 for (auto &RefExpr : VarList) { 04527 assert(RefExpr && "NULL expr in OpenMP shared clause."); 04528 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 04529 // It will be analyzed later. 04530 Vars.push_back(RefExpr); 04531 continue; 04532 } 04533 04534 SourceLocation ELoc = RefExpr->getExprLoc(); 04535 // OpenMP [2.1, C/C++] 04536 // A list item is a variable name. 04537 // OpenMP [2.14.3.2, Restrictions, p.1] 04538 // A variable that is part of another variable (as an array or structure 04539 // element) cannot appear in a shared unless it is a static data member 04540 // of a C++ class. 04541 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 04542 if (!DE || !isa<VarDecl>(DE->getDecl())) { 04543 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 04544 continue; 04545 } 04546 Decl *D = DE->getDecl(); 04547 VarDecl *VD = cast<VarDecl>(D); 04548 04549 QualType Type = VD->getType(); 04550 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 04551 // It will be analyzed later. 04552 Vars.push_back(DE); 04553 continue; 04554 } 04555 04556 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 04557 // in a Construct] 04558 // Variables with the predetermined data-sharing attributes may not be 04559 // listed in data-sharing attributes clauses, except for the cases 04560 // listed below. For these exceptions only, listing a predetermined 04561 // variable in a data-sharing attribute clause is allowed and overrides 04562 // the variable's predetermined data-sharing attributes. 04563 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 04564 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 04565 DVar.RefExpr) { 04566 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 04567 << getOpenMPClauseName(OMPC_shared); 04568 ReportOriginalDSA(*this, DSAStack, VD, DVar); 04569 continue; 04570 } 04571 04572 DSAStack->addDSA(VD, DE, OMPC_shared); 04573 Vars.push_back(DE); 04574 } 04575 04576 if (Vars.empty()) 04577 return nullptr; 04578 04579 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 04580 } 04581 04582 namespace { 04583 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 04584 DSAStackTy *Stack; 04585 04586 public: 04587 bool VisitDeclRefExpr(DeclRefExpr *E) { 04588 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 04589 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 04590 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 04591 return false; 04592 if (DVar.CKind != OMPC_unknown) 04593 return true; 04594 DSAStackTy::DSAVarData DVarPrivate = 04595 Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), false); 04596 if (DVarPrivate.CKind != OMPC_unknown) 04597 return true; 04598 return false; 04599 } 04600 return false; 04601 } 04602 bool VisitStmt(Stmt *S) { 04603 for (auto Child : S->children()) { 04604 if (Child && Visit(Child)) 04605 return true; 04606 } 04607 return false; 04608 } 04609 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 04610 }; 04611 } // namespace 04612 04613 OMPClause *Sema::ActOnOpenMPReductionClause( 04614 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 04615 SourceLocation ColonLoc, SourceLocation EndLoc, 04616 CXXScopeSpec &ReductionIdScopeSpec, 04617 const DeclarationNameInfo &ReductionId) { 04618 // TODO: Allow scope specification search when 'declare reduction' is 04619 // supported. 04620 assert(ReductionIdScopeSpec.isEmpty() && 04621 "No support for scoped reduction identifiers yet."); 04622 04623 auto DN = ReductionId.getName(); 04624 auto OOK = DN.getCXXOverloadedOperator(); 04625 BinaryOperatorKind BOK = BO_Comma; 04626 04627 // OpenMP [2.14.3.6, reduction clause] 04628 // C 04629 // reduction-identifier is either an identifier or one of the following 04630 // operators: +, -, *, &, |, ^, && and || 04631 // C++ 04632 // reduction-identifier is either an id-expression or one of the following 04633 // operators: +, -, *, &, |, ^, && and || 04634 // FIXME: Only 'min' and 'max' identifiers are supported for now. 04635 switch (OOK) { 04636 case OO_Plus: 04637 case OO_Minus: 04638 BOK = BO_AddAssign; 04639 break; 04640 case OO_Star: 04641 BOK = BO_MulAssign; 04642 break; 04643 case OO_Amp: 04644 BOK = BO_AndAssign; 04645 break; 04646 case OO_Pipe: 04647 BOK = BO_OrAssign; 04648 break; 04649 case OO_Caret: 04650 BOK = BO_XorAssign; 04651 break; 04652 case OO_AmpAmp: 04653 BOK = BO_LAnd; 04654 break; 04655 case OO_PipePipe: 04656 BOK = BO_LOr; 04657 break; 04658 default: 04659 if (auto II = DN.getAsIdentifierInfo()) { 04660 if (II->isStr("max")) 04661 BOK = BO_GT; 04662 else if (II->isStr("min")) 04663 BOK = BO_LT; 04664 } 04665 break; 04666 } 04667 SourceRange ReductionIdRange; 04668 if (ReductionIdScopeSpec.isValid()) { 04669 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 04670 } 04671 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 04672 if (BOK == BO_Comma) { 04673 // Not allowed reduction identifier is found. 04674 Diag(ReductionId.getLocStart(), diag::err_omp_unknown_reduction_identifier) 04675 << ReductionIdRange; 04676 return nullptr; 04677 } 04678 04679 SmallVector<Expr *, 8> Vars; 04680 for (auto RefExpr : VarList) { 04681 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 04682 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 04683 // It will be analyzed later. 04684 Vars.push_back(RefExpr); 04685 continue; 04686 } 04687 04688 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 04689 RefExpr->isInstantiationDependent() || 04690 RefExpr->containsUnexpandedParameterPack()) { 04691 // It will be analyzed later. 04692 Vars.push_back(RefExpr); 04693 continue; 04694 } 04695 04696 auto ELoc = RefExpr->getExprLoc(); 04697 auto ERange = RefExpr->getSourceRange(); 04698 // OpenMP [2.1, C/C++] 04699 // A list item is a variable or array section, subject to the restrictions 04700 // specified in Section 2.4 on page 42 and in each of the sections 04701 // describing clauses and directives for which a list appears. 04702 // OpenMP [2.14.3.3, Restrictions, p.1] 04703 // A variable that is part of another variable (as an array or 04704 // structure element) cannot appear in a private clause. 04705 auto DE = dyn_cast<DeclRefExpr>(RefExpr); 04706 if (!DE || !isa<VarDecl>(DE->getDecl())) { 04707 Diag(ELoc, diag::err_omp_expected_var_name) << ERange; 04708 continue; 04709 } 04710 auto D = DE->getDecl(); 04711 auto VD = cast<VarDecl>(D); 04712 auto Type = VD->getType(); 04713 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 04714 // A variable that appears in a private clause must not have an incomplete 04715 // type or a reference type. 04716 if (RequireCompleteType(ELoc, Type, 04717 diag::err_omp_reduction_incomplete_type)) 04718 continue; 04719 // OpenMP [2.14.3.6, reduction clause, Restrictions] 04720 // Arrays may not appear in a reduction clause. 04721 if (Type.getNonReferenceType()->isArrayType()) { 04722 Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange; 04723 bool IsDecl = 04724 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 04725 Diag(VD->getLocation(), 04726 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04727 << VD; 04728 continue; 04729 } 04730 // OpenMP [2.14.3.6, reduction clause, Restrictions] 04731 // A list item that appears in a reduction clause must not be 04732 // const-qualified. 04733 if (Type.getNonReferenceType().isConstant(Context)) { 04734 Diag(ELoc, diag::err_omp_const_variable) 04735 << getOpenMPClauseName(OMPC_reduction) << Type << ERange; 04736 bool IsDecl = 04737 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 04738 Diag(VD->getLocation(), 04739 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04740 << VD; 04741 continue; 04742 } 04743 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 04744 // If a list-item is a reference type then it must bind to the same object 04745 // for all threads of the team. 04746 VarDecl *VDDef = VD->getDefinition(); 04747 if (Type->isReferenceType() && VDDef) { 04748 DSARefChecker Check(DSAStack); 04749 if (Check.Visit(VDDef->getInit())) { 04750 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; 04751 Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 04752 continue; 04753 } 04754 } 04755 // OpenMP [2.14.3.6, reduction clause, Restrictions] 04756 // The type of a list item that appears in a reduction clause must be valid 04757 // for the reduction-identifier. For a max or min reduction in C, the type 04758 // of the list item must be an allowed arithmetic data type: char, int, 04759 // float, double, or _Bool, possibly modified with long, short, signed, or 04760 // unsigned. For a max or min reduction in C++, the type of the list item 04761 // must be an allowed arithmetic data type: char, wchar_t, int, float, 04762 // double, or bool, possibly modified with long, short, signed, or unsigned. 04763 if ((BOK == BO_GT || BOK == BO_LT) && 04764 !(Type->isScalarType() || 04765 (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 04766 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 04767 << getLangOpts().CPlusPlus; 04768 bool IsDecl = 04769 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 04770 Diag(VD->getLocation(), 04771 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04772 << VD; 04773 continue; 04774 } 04775 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 04776 !getLangOpts().CPlusPlus && Type->isFloatingType()) { 04777 Diag(ELoc, diag::err_omp_clause_floating_type_arg); 04778 bool IsDecl = 04779 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 04780 Diag(VD->getLocation(), 04781 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04782 << VD; 04783 continue; 04784 } 04785 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 04786 getDiagnostics().setSuppressAllDiagnostics(true); 04787 ExprResult ReductionOp = 04788 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BOK, 04789 RefExpr, RefExpr); 04790 getDiagnostics().setSuppressAllDiagnostics(Suppress); 04791 if (ReductionOp.isInvalid()) { 04792 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type 04793 << ReductionIdRange; 04794 bool IsDecl = 04795 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 04796 Diag(VD->getLocation(), 04797 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04798 << VD; 04799 continue; 04800 } 04801 04802 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 04803 // in a Construct] 04804 // Variables with the predetermined data-sharing attributes may not be 04805 // listed in data-sharing attributes clauses, except for the cases 04806 // listed below. For these exceptions only, listing a predetermined 04807 // variable in a data-sharing attribute clause is allowed and overrides 04808 // the variable's predetermined data-sharing attributes. 04809 // OpenMP [2.14.3.6, Restrictions, p.3] 04810 // Any number of reduction clauses can be specified on the directive, 04811 // but a list item can appear only once in the reduction clauses for that 04812 // directive. 04813 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 04814 if (DVar.CKind == OMPC_reduction) { 04815 Diag(ELoc, diag::err_omp_once_referenced) 04816 << getOpenMPClauseName(OMPC_reduction); 04817 if (DVar.RefExpr) { 04818 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 04819 } 04820 } else if (DVar.CKind != OMPC_unknown) { 04821 Diag(ELoc, diag::err_omp_wrong_dsa) 04822 << getOpenMPClauseName(DVar.CKind) 04823 << getOpenMPClauseName(OMPC_reduction); 04824 ReportOriginalDSA(*this, DSAStack, VD, DVar); 04825 continue; 04826 } 04827 04828 // OpenMP [2.14.3.6, Restrictions, p.1] 04829 // A list item that appears in a reduction clause of a worksharing 04830 // construct must be shared in the parallel regions to which any of the 04831 // worksharing regions arising from the worksharing construct bind. 04832 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 04833 if (isOpenMPWorksharingDirective(CurrDir) && 04834 !isOpenMPParallelDirective(CurrDir)) { 04835 DVar = DSAStack->getImplicitDSA(VD, true); 04836 if (DVar.CKind != OMPC_shared) { 04837 Diag(ELoc, diag::err_omp_required_access) 04838 << getOpenMPClauseName(OMPC_reduction) 04839 << getOpenMPClauseName(OMPC_shared); 04840 ReportOriginalDSA(*this, DSAStack, VD, DVar); 04841 continue; 04842 } 04843 } 04844 04845 CXXRecordDecl *RD = getLangOpts().CPlusPlus 04846 ? Type.getNonReferenceType()->getAsCXXRecordDecl() 04847 : nullptr; 04848 // FIXME This code must be replaced by actual constructing/destructing of 04849 // the reduction variable. 04850 if (RD) { 04851 CXXConstructorDecl *CD = LookupDefaultConstructor(RD); 04852 PartialDiagnostic PD = 04853 PartialDiagnostic(PartialDiagnostic::NullDiagnostic()); 04854 if (!CD || 04855 CheckConstructorAccess(ELoc, CD, 04856 InitializedEntity::InitializeTemporary(Type), 04857 CD->getAccess(), PD) == AR_inaccessible || 04858 CD->isDeleted()) { 04859 Diag(ELoc, diag::err_omp_required_method) 04860 << getOpenMPClauseName(OMPC_reduction) << 0; 04861 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 04862 VarDecl::DeclarationOnly; 04863 Diag(VD->getLocation(), 04864 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04865 << VD; 04866 Diag(RD->getLocation(), diag::note_previous_decl) << RD; 04867 continue; 04868 } 04869 MarkFunctionReferenced(ELoc, CD); 04870 DiagnoseUseOfDecl(CD, ELoc); 04871 04872 CXXDestructorDecl *DD = RD->getDestructor(); 04873 if (DD) { 04874 if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible || 04875 DD->isDeleted()) { 04876 Diag(ELoc, diag::err_omp_required_method) 04877 << getOpenMPClauseName(OMPC_reduction) << 4; 04878 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 04879 VarDecl::DeclarationOnly; 04880 Diag(VD->getLocation(), 04881 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04882 << VD; 04883 Diag(RD->getLocation(), diag::note_previous_decl) << RD; 04884 continue; 04885 } 04886 MarkFunctionReferenced(ELoc, DD); 04887 DiagnoseUseOfDecl(DD, ELoc); 04888 } 04889 } 04890 04891 DSAStack->addDSA(VD, DE, OMPC_reduction); 04892 Vars.push_back(DE); 04893 } 04894 04895 if (Vars.empty()) 04896 return nullptr; 04897 04898 return OMPReductionClause::Create( 04899 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, 04900 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId); 04901 } 04902 04903 OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, 04904 SourceLocation StartLoc, 04905 SourceLocation LParenLoc, 04906 SourceLocation ColonLoc, 04907 SourceLocation EndLoc) { 04908 SmallVector<Expr *, 8> Vars; 04909 for (auto &RefExpr : VarList) { 04910 assert(RefExpr && "NULL expr in OpenMP linear clause."); 04911 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 04912 // It will be analyzed later. 04913 Vars.push_back(RefExpr); 04914 continue; 04915 } 04916 04917 // OpenMP [2.14.3.7, linear clause] 04918 // A list item that appears in a linear clause is subject to the private 04919 // clause semantics described in Section 2.14.3.3 on page 159 except as 04920 // noted. In addition, the value of the new list item on each iteration 04921 // of the associated loop(s) corresponds to the value of the original 04922 // list item before entering the construct plus the logical number of 04923 // the iteration times linear-step. 04924 04925 SourceLocation ELoc = RefExpr->getExprLoc(); 04926 // OpenMP [2.1, C/C++] 04927 // A list item is a variable name. 04928 // OpenMP [2.14.3.3, Restrictions, p.1] 04929 // A variable that is part of another variable (as an array or 04930 // structure element) cannot appear in a private clause. 04931 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 04932 if (!DE || !isa<VarDecl>(DE->getDecl())) { 04933 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 04934 continue; 04935 } 04936 04937 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 04938 04939 // OpenMP [2.14.3.7, linear clause] 04940 // A list-item cannot appear in more than one linear clause. 04941 // A list-item that appears in a linear clause cannot appear in any 04942 // other data-sharing attribute clause. 04943 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 04944 if (DVar.RefExpr) { 04945 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 04946 << getOpenMPClauseName(OMPC_linear); 04947 ReportOriginalDSA(*this, DSAStack, VD, DVar); 04948 continue; 04949 } 04950 04951 QualType QType = VD->getType(); 04952 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 04953 // It will be analyzed later. 04954 Vars.push_back(DE); 04955 continue; 04956 } 04957 04958 // A variable must not have an incomplete type or a reference type. 04959 if (RequireCompleteType(ELoc, QType, 04960 diag::err_omp_linear_incomplete_type)) { 04961 continue; 04962 } 04963 if (QType->isReferenceType()) { 04964 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 04965 << getOpenMPClauseName(OMPC_linear) << QType; 04966 bool IsDecl = 04967 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 04968 Diag(VD->getLocation(), 04969 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04970 << VD; 04971 continue; 04972 } 04973 04974 // A list item must not be const-qualified. 04975 if (QType.isConstant(Context)) { 04976 Diag(ELoc, diag::err_omp_const_variable) 04977 << getOpenMPClauseName(OMPC_linear); 04978 bool IsDecl = 04979 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 04980 Diag(VD->getLocation(), 04981 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04982 << VD; 04983 continue; 04984 } 04985 04986 // A list item must be of integral or pointer type. 04987 QType = QType.getUnqualifiedType().getCanonicalType(); 04988 const Type *Ty = QType.getTypePtrOrNull(); 04989 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 04990 !Ty->isPointerType())) { 04991 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType; 04992 bool IsDecl = 04993 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 04994 Diag(VD->getLocation(), 04995 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 04996 << VD; 04997 continue; 04998 } 04999 05000 DSAStack->addDSA(VD, DE, OMPC_linear); 05001 Vars.push_back(DE); 05002 } 05003 05004 if (Vars.empty()) 05005 return nullptr; 05006 05007 Expr *StepExpr = Step; 05008 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 05009 !Step->isInstantiationDependent() && 05010 !Step->containsUnexpandedParameterPack()) { 05011 SourceLocation StepLoc = Step->getLocStart(); 05012 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 05013 if (Val.isInvalid()) 05014 return nullptr; 05015 StepExpr = Val.get(); 05016 05017 // Warn about zero linear step (it would be probably better specified as 05018 // making corresponding variables 'const'). 05019 llvm::APSInt Result; 05020 if (StepExpr->isIntegerConstantExpr(Result, Context) && 05021 !Result.isNegative() && !Result.isStrictlyPositive()) 05022 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 05023 << (Vars.size() > 1); 05024 } 05025 05026 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, ColonLoc, EndLoc, 05027 Vars, StepExpr); 05028 } 05029 05030 OMPClause *Sema::ActOnOpenMPAlignedClause( 05031 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 05032 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 05033 05034 SmallVector<Expr *, 8> Vars; 05035 for (auto &RefExpr : VarList) { 05036 assert(RefExpr && "NULL expr in OpenMP aligned clause."); 05037 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 05038 // It will be analyzed later. 05039 Vars.push_back(RefExpr); 05040 continue; 05041 } 05042 05043 SourceLocation ELoc = RefExpr->getExprLoc(); 05044 // OpenMP [2.1, C/C++] 05045 // A list item is a variable name. 05046 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 05047 if (!DE || !isa<VarDecl>(DE->getDecl())) { 05048 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 05049 continue; 05050 } 05051 05052 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 05053 05054 // OpenMP [2.8.1, simd construct, Restrictions] 05055 // The type of list items appearing in the aligned clause must be 05056 // array, pointer, reference to array, or reference to pointer. 05057 QualType QType = DE->getType() 05058 .getNonReferenceType() 05059 .getUnqualifiedType() 05060 .getCanonicalType(); 05061 const Type *Ty = QType.getTypePtrOrNull(); 05062 if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() && 05063 !Ty->isPointerType())) { 05064 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 05065 << QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange(); 05066 bool IsDecl = 05067 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 05068 Diag(VD->getLocation(), 05069 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 05070 << VD; 05071 continue; 05072 } 05073 05074 // OpenMP [2.8.1, simd construct, Restrictions] 05075 // A list-item cannot appear in more than one aligned clause. 05076 if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) { 05077 Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange(); 05078 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 05079 << getOpenMPClauseName(OMPC_aligned); 05080 continue; 05081 } 05082 05083 Vars.push_back(DE); 05084 } 05085 05086 // OpenMP [2.8.1, simd construct, Description] 05087 // The parameter of the aligned clause, alignment, must be a constant 05088 // positive integer expression. 05089 // If no optional parameter is specified, implementation-defined default 05090 // alignments for SIMD instructions on the target platforms are assumed. 05091 if (Alignment != nullptr) { 05092 ExprResult AlignResult = 05093 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 05094 if (AlignResult.isInvalid()) 05095 return nullptr; 05096 Alignment = AlignResult.get(); 05097 } 05098 if (Vars.empty()) 05099 return nullptr; 05100 05101 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 05102 EndLoc, Vars, Alignment); 05103 } 05104 05105 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 05106 SourceLocation StartLoc, 05107 SourceLocation LParenLoc, 05108 SourceLocation EndLoc) { 05109 SmallVector<Expr *, 8> Vars; 05110 for (auto &RefExpr : VarList) { 05111 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 05112 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 05113 // It will be analyzed later. 05114 Vars.push_back(RefExpr); 05115 continue; 05116 } 05117 05118 SourceLocation ELoc = RefExpr->getExprLoc(); 05119 // OpenMP [2.1, C/C++] 05120 // A list item is a variable name. 05121 // OpenMP [2.14.4.1, Restrictions, p.1] 05122 // A list item that appears in a copyin clause must be threadprivate. 05123 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 05124 if (!DE || !isa<VarDecl>(DE->getDecl())) { 05125 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 05126 continue; 05127 } 05128 05129 Decl *D = DE->getDecl(); 05130 VarDecl *VD = cast<VarDecl>(D); 05131 05132 QualType Type = VD->getType(); 05133 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 05134 // It will be analyzed later. 05135 Vars.push_back(DE); 05136 continue; 05137 } 05138 05139 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 05140 // A list item that appears in a copyin clause must be threadprivate. 05141 if (!DSAStack->isThreadPrivate(VD)) { 05142 Diag(ELoc, diag::err_omp_required_access) 05143 << getOpenMPClauseName(OMPC_copyin) 05144 << getOpenMPDirectiveName(OMPD_threadprivate); 05145 continue; 05146 } 05147 05148 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 05149 // A variable of class type (or array thereof) that appears in a 05150 // copyin clause requires an accessible, unambiguous copy assignment 05151 // operator for the class type. 05152 Type = Context.getBaseElementType(Type); 05153 CXXRecordDecl *RD = 05154 getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 05155 // FIXME This code must be replaced by actual assignment of the 05156 // threadprivate variable. 05157 if (RD) { 05158 CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0); 05159 DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess()); 05160 if (MD) { 05161 if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible || 05162 MD->isDeleted()) { 05163 Diag(ELoc, diag::err_omp_required_method) 05164 << getOpenMPClauseName(OMPC_copyin) << 2; 05165 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 05166 VarDecl::DeclarationOnly; 05167 Diag(VD->getLocation(), 05168 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 05169 << VD; 05170 Diag(RD->getLocation(), diag::note_previous_decl) << RD; 05171 continue; 05172 } 05173 MarkFunctionReferenced(ELoc, MD); 05174 DiagnoseUseOfDecl(MD, ELoc); 05175 } 05176 } 05177 05178 DSAStack->addDSA(VD, DE, OMPC_copyin); 05179 Vars.push_back(DE); 05180 } 05181 05182 if (Vars.empty()) 05183 return nullptr; 05184 05185 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 05186 } 05187 05188 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 05189 SourceLocation StartLoc, 05190 SourceLocation LParenLoc, 05191 SourceLocation EndLoc) { 05192 SmallVector<Expr *, 8> Vars; 05193 for (auto &RefExpr : VarList) { 05194 assert(RefExpr && "NULL expr in OpenMP copyprivate clause."); 05195 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 05196 // It will be analyzed later. 05197 Vars.push_back(RefExpr); 05198 continue; 05199 } 05200 05201 SourceLocation ELoc = RefExpr->getExprLoc(); 05202 // OpenMP [2.1, C/C++] 05203 // A list item is a variable name. 05204 // OpenMP [2.14.4.1, Restrictions, p.1] 05205 // A list item that appears in a copyin clause must be threadprivate. 05206 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 05207 if (!DE || !isa<VarDecl>(DE->getDecl())) { 05208 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 05209 continue; 05210 } 05211 05212 Decl *D = DE->getDecl(); 05213 VarDecl *VD = cast<VarDecl>(D); 05214 05215 QualType Type = VD->getType(); 05216 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 05217 // It will be analyzed later. 05218 Vars.push_back(DE); 05219 continue; 05220 } 05221 05222 // OpenMP [2.14.4.2, Restrictions, p.2] 05223 // A list item that appears in a copyprivate clause may not appear in a 05224 // private or firstprivate clause on the single construct. 05225 if (!DSAStack->isThreadPrivate(VD)) { 05226 auto DVar = DSAStack->getTopDSA(VD, false); 05227 if (DVar.CKind != OMPC_copyprivate && DVar.CKind != OMPC_unknown && 05228 !(DVar.CKind == OMPC_private && !DVar.RefExpr)) { 05229 Diag(ELoc, diag::err_omp_wrong_dsa) 05230 << getOpenMPClauseName(DVar.CKind) 05231 << getOpenMPClauseName(OMPC_copyprivate); 05232 ReportOriginalDSA(*this, DSAStack, VD, DVar); 05233 continue; 05234 } 05235 05236 // OpenMP [2.11.4.2, Restrictions, p.1] 05237 // All list items that appear in a copyprivate clause must be either 05238 // threadprivate or private in the enclosing context. 05239 if (DVar.CKind == OMPC_unknown) { 05240 DVar = DSAStack->getImplicitDSA(VD, false); 05241 if (DVar.CKind == OMPC_shared) { 05242 Diag(ELoc, diag::err_omp_required_access) 05243 << getOpenMPClauseName(OMPC_copyprivate) 05244 << "threadprivate or private in the enclosing context"; 05245 ReportOriginalDSA(*this, DSAStack, VD, DVar); 05246 continue; 05247 } 05248 } 05249 } 05250 05251 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 05252 // A variable of class type (or array thereof) that appears in a 05253 // copyin clause requires an accessible, unambiguous copy assignment 05254 // operator for the class type. 05255 Type = Context.getBaseElementType(Type); 05256 CXXRecordDecl *RD = 05257 getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 05258 // FIXME This code must be replaced by actual assignment of the 05259 // threadprivate variable. 05260 if (RD) { 05261 CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0); 05262 DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess()); 05263 if (MD) { 05264 if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible || 05265 MD->isDeleted()) { 05266 Diag(ELoc, diag::err_omp_required_method) 05267 << getOpenMPClauseName(OMPC_copyprivate) << 2; 05268 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 05269 VarDecl::DeclarationOnly; 05270 Diag(VD->getLocation(), 05271 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 05272 << VD; 05273 Diag(RD->getLocation(), diag::note_previous_decl) << RD; 05274 continue; 05275 } 05276 MarkFunctionReferenced(ELoc, MD); 05277 DiagnoseUseOfDecl(MD, ELoc); 05278 } 05279 } 05280 05281 // No need to mark vars as copyprivate, they are already threadprivate or 05282 // implicitly private. 05283 Vars.push_back(DE); 05284 } 05285 05286 if (Vars.empty()) 05287 return nullptr; 05288 05289 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 05290 } 05291 05292 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 05293 SourceLocation StartLoc, 05294 SourceLocation LParenLoc, 05295 SourceLocation EndLoc) { 05296 if (VarList.empty()) 05297 return nullptr; 05298 05299 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 05300 } 05301