Author: abataev Date: Wed Jan 20 03:07:54 2016 New Revision: 258299 URL: http://llvm.org/viewvc/llvm-project?rev=258299&view=rev Log: [OPENMP 4.5] Allow to use non-static data members in non-static member functions in 'private' clause. OpenMP 4.5 allows to use non-static members of current class in non-static member functions in 'private' clause. Patch adds initial support for privatizing data members.
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaOpenMP.cpp cfe/trunk/test/OpenMP/distribute_ast_print.cpp cfe/trunk/test/OpenMP/for_ast_print.cpp cfe/trunk/test/OpenMP/for_private_messages.cpp cfe/trunk/test/OpenMP/for_simd_ast_print.cpp cfe/trunk/test/OpenMP/for_simd_private_messages.cpp cfe/trunk/test/OpenMP/parallel_ast_print.cpp cfe/trunk/test/OpenMP/parallel_for_ast_print.cpp cfe/trunk/test/OpenMP/parallel_for_private_messages.cpp cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp cfe/trunk/test/OpenMP/parallel_for_simd_private_messages.cpp cfe/trunk/test/OpenMP/parallel_sections_private_messages.cpp cfe/trunk/test/OpenMP/sections_private_messages.cpp cfe/trunk/test/OpenMP/simd_private_messages.cpp cfe/trunk/test/OpenMP/single_private_messages.cpp cfe/trunk/test/OpenMP/target_private_messages.cpp cfe/trunk/test/OpenMP/task_ast_print.cpp cfe/trunk/test/OpenMP/taskloop_private_messages.cpp cfe/trunk/test/OpenMP/taskloop_simd_private_messages.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jan 20 03:07:54 2016 @@ -7710,10 +7710,10 @@ def err_omp_reduction_incomplete_type : "a reduction list item with incomplete type %0">; def err_omp_unexpected_clause_value : Error< "expected %0 in OpenMP clause '%1'">; -def err_omp_expected_var_name : Error< - "expected variable name">; -def err_omp_expected_var_name_or_array_item : Error< - "expected variable name, array element or array section">; +def err_omp_expected_var_name_member_expr : Error< + "expected variable name%select{| or data member of current class}0">; +def err_omp_expected_var_name_member_expr_or_array_item : Error< + "expected variable name%select{|, data member of current class}0, array element or array section">; def note_omp_task_predetermined_firstprivate_here : Note< "predetermined as a firstprivate in a task construct here">; def err_omp_threadprivate_incomplete_type : Error< Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Wed Jan 20 03:07:54 2016 @@ -7778,23 +7778,23 @@ public: /// \brief Return true if the provided declaration \a VD should be captured by /// reference in the provided scope \a RSI. This will take into account the /// semantics of the directive and associated clauses. - bool IsOpenMPCapturedByRef(VarDecl *VD, + bool IsOpenMPCapturedByRef(ValueDecl *D, const sema::CapturedRegionScopeInfo *RSI); /// \brief Check if the specified variable is used in one of the private /// clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP /// constructs. - bool IsOpenMPCapturedVar(VarDecl *VD); + bool IsOpenMPCapturedDecl(ValueDecl *D); /// \brief Check if the specified variable is used in 'private' clause. /// \param Level Relative level of nested OpenMP construct for that the check /// is performed. - bool isOpenMPPrivateVar(VarDecl *VD, unsigned Level); + bool isOpenMPPrivateDecl(ValueDecl *D, unsigned Level); /// \brief Check if the specified variable is captured by 'target' directive. /// \param Level Relative level of nested OpenMP construct for that the check /// is performed. - bool isOpenMPTargetCapturedVar(VarDecl *VD, unsigned Level); + bool isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level); ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op); @@ -7854,19 +7854,19 @@ public: StmtResult ActOnOpenMPSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp for' after parsing /// of the associated statement. StmtResult ActOnOpenMPForDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp for simd' after parsing /// of the associated statement. StmtResult ActOnOpenMPForSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp sections' after parsing /// of the associated statement. StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, @@ -7896,13 +7896,13 @@ public: StmtResult ActOnOpenMPParallelForDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp parallel for simd' after /// parsing of the associated statement. StmtResult ActOnOpenMPParallelForSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp parallel sections' after /// parsing of the associated statement. StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, @@ -7980,19 +7980,19 @@ public: StmtResult ActOnOpenMPTaskLoopDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp taskloop simd' after parsing of /// the associated statement. StmtResult ActOnOpenMPTaskLoopSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp distribute' after parsing /// of the associated statement. StmtResult ActOnOpenMPDistributeDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Jan 20 03:07:54 2016 @@ -12894,7 +12894,7 @@ static bool captureInCapturedRegion(Capt // Using an LValue reference type is consistent with Lambdas (see below). if (S.getLangOpts().OpenMP) { ByRef = S.IsOpenMPCapturedByRef(Var, RSI); - if (S.IsOpenMPCapturedVar(Var)) + if (S.IsOpenMPCapturedDecl(Var)) DeclRefType = DeclRefType.getUnqualifiedType(); } @@ -13085,7 +13085,7 @@ bool Sema::tryCaptureVariable( // Capture global variables if it is required to use private copy of this // variable. bool IsGlobal = !Var->hasLocalStorage(); - if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedVar(Var))) + if (IsGlobal && !(LangOpts.OpenMP && IsOpenMPCapturedDecl(Var))) return true; // Walk up the stack to determine whether we can capture the variable, @@ -13280,14 +13280,14 @@ bool Sema::tryCaptureVariable( // just break here. Similarly, global variables that are captured in a // target region should not be captured outside the scope of the region. if (RSI->CapRegionKind == CR_OpenMP) { - auto isTargetCap = isOpenMPTargetCapturedVar(Var, OpenMPLevel); + auto isTargetCap = isOpenMPTargetCapturedDecl(Var, OpenMPLevel); // When we detect target captures we are looking from inside the // target region, therefore we need to propagate the capture from the // enclosing region. Therefore, the capture is not initially nested. if (isTargetCap) FunctionScopesIndex--; - if (isTargetCap || isOpenMPPrivateVar(Var, OpenMPLevel)) { + if (isTargetCap || isOpenMPPrivateDecl(Var, OpenMPLevel)) { Nested = !isTargetCap; DeclRefType = DeclRefType.getUnqualifiedType(); CaptureType = Context.getLValueReferenceType(DeclRefType); Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Wed Jan 20 03:07:54 2016 @@ -70,7 +70,7 @@ public: struct DSAVarData { OpenMPDirectiveKind DKind; OpenMPClauseKind CKind; - DeclRefExpr *RefExpr; + Expr *RefExpr; SourceLocation ImplicitDSALoc; DSAVarData() : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr), @@ -85,12 +85,12 @@ public: private: struct DSAInfo { OpenMPClauseKind Attributes; - DeclRefExpr *RefExpr; + Expr *RefExpr; }; - typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy; - typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy; - typedef llvm::DenseMap<VarDecl *, unsigned> LoopControlVariablesMapTy; - typedef llvm::SmallDenseMap<VarDecl *, MapInfo, 64> MappedDeclsTy; + typedef llvm::SmallDenseMap<ValueDecl *, DSAInfo, 64> DeclSAMapTy; + typedef llvm::SmallDenseMap<ValueDecl *, Expr *, 64> AlignedMapTy; + typedef llvm::DenseMap<ValueDecl *, unsigned> LoopControlVariablesMapTy; + typedef llvm::SmallDenseMap<ValueDecl *, MapInfo, 64> MappedDeclsTy; typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>> CriticalsWithHintsTy; @@ -139,7 +139,7 @@ private: typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; - DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D); + DSAVarData getDSA(StackTy::reverse_iterator Iter, ValueDecl *D); /// \brief Checks if the variable is a local for OpenMP region. bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); @@ -179,49 +179,48 @@ public: /// \brief If 'aligned' declaration for given variable \a D was not seen yet, /// add it and return NULL; otherwise return previous occurrence's expression /// for diagnostics. - DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE); + Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE); /// \brief Register specified variable as loop control variable. - void addLoopControlVariable(VarDecl *D); + void addLoopControlVariable(ValueDecl *D); /// \brief Check if the specified variable is a loop control variable for /// current region. /// \return The index of the loop control variable in the list of associated /// for-loops (from outer to inner). - unsigned isLoopControlVariable(VarDecl *D); + unsigned isLoopControlVariable(ValueDecl *D); /// \brief Check if the specified variable is a loop control variable for /// parent region. /// \return The index of the loop control variable in the list of associated /// for-loops (from outer to inner). - unsigned isParentLoopControlVariable(VarDecl *D); + unsigned isParentLoopControlVariable(ValueDecl *D); /// \brief Get the loop control variable for the I-th loop (or nullptr) in /// parent directive. - VarDecl *getParentLoopControlVariable(unsigned I); + ValueDecl *getParentLoopControlVariable(unsigned I); /// \brief Adds explicit data sharing attribute to the specified declaration. - void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A); + void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A); /// \brief Returns data sharing attributes from top of the stack for the /// specified declaration. - DSAVarData getTopDSA(VarDecl *D, bool FromParent); + DSAVarData getTopDSA(ValueDecl *D, bool FromParent); /// \brief Returns data-sharing attributes for the specified declaration. - DSAVarData getImplicitDSA(VarDecl *D, bool FromParent); + DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent); /// \brief Checks if the specified variables has data-sharing attributes which /// match specified \a CPred predicate in any directive which matches \a DPred /// predicate. template <class ClausesPredicate, class DirectivesPredicate> - DSAVarData hasDSA(VarDecl *D, ClausesPredicate CPred, + DSAVarData hasDSA(ValueDecl *D, ClausesPredicate CPred, DirectivesPredicate DPred, bool FromParent); /// \brief Checks if the specified variables has data-sharing attributes which /// match specified \a CPred predicate in any innermost directive which /// matches \a DPred predicate. template <class ClausesPredicate, class DirectivesPredicate> - DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, - DirectivesPredicate DPred, - bool FromParent); + DSAVarData hasInnermostDSA(ValueDecl *D, ClausesPredicate CPred, + DirectivesPredicate DPred, bool FromParent); /// \brief Checks if the specified variables has explicit data-sharing /// attributes which match specified \a CPred predicate at the specified /// OpenMP region. - bool hasExplicitDSA(VarDecl *D, + bool hasExplicitDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, unsigned Level); @@ -338,7 +337,7 @@ public: Scope *getCurScope() { return Stack.back().CurScope; } SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } - MapInfo getMapInfoForVar(VarDecl *VD) { + MapInfo getMapInfoForVar(ValueDecl *VD) { MapInfo VarMI = {0}; for (auto Cnt = Stack.size() - 1; Cnt > 0; --Cnt) { if (Stack[Cnt].MappedDecls.count(VD)) { @@ -349,13 +348,13 @@ public: return VarMI; } - void addMapInfoForVar(VarDecl *VD, MapInfo MI) { + void addMapInfoForVar(ValueDecl *VD, MapInfo MI) { if (Stack.size() > 1) { Stack.back().MappedDecls[VD] = MI; } } - MapInfo IsMappedInCurrentRegion(VarDecl *VD) { + MapInfo IsMappedInCurrentRegion(ValueDecl *VD) { assert(Stack.size() > 1 && "Target level is 0"); MapInfo VarMI = {0}; if (Stack.size() > 1 && Stack.back().MappedDecls.count(VD)) { @@ -371,9 +370,25 @@ bool isParallelOrTaskRegion(OpenMPDirect } } // namespace +static ValueDecl *getCanonicalDecl(ValueDecl *D) { + auto *VD = dyn_cast<VarDecl>(D); + auto *FD = dyn_cast<FieldDecl>(D); + if (VD != nullptr) { + VD = VD->getCanonicalDecl(); + D = VD; + } else { + assert(FD); + FD = FD->getCanonicalDecl(); + D = FD; + } + return D; +} + DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter, - VarDecl *D) { - D = D->getCanonicalDecl(); + ValueDecl *D) { + D = getCanonicalDecl(D); + auto *VD = dyn_cast<VarDecl>(D); + auto *FD = dyn_cast<FieldDecl>(D); DSAVarData DVar; if (Iter == std::prev(Stack.rend())) { // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced @@ -381,14 +396,18 @@ DSAStackTy::DSAVarData DSAStackTy::getDS // File-scope or namespace-scope variables referenced in called routines // in the region are shared unless they appear in a threadprivate // directive. - if (!D->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) + if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) DVar.CKind = OMPC_shared; // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced // in a region but not in construct] // Variables with static storage duration that are declared in called // routines in the region are shared. - if (D->hasGlobalStorage()) + if (VD && VD->hasGlobalStorage()) + DVar.CKind = OMPC_shared; + + // Non-static data members are shared by default. + if (FD) DVar.CKind = OMPC_shared; return DVar; @@ -399,8 +418,8 @@ DSAStackTy::DSAVarData DSAStackTy::getDS // in a Construct, C/C++, predetermined, p.1] // Variables with automatic storage duration that are declared in a scope // inside the construct are private. - if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() && - (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) { + if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && + (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { DVar.CKind = OMPC_private; return DVar; } @@ -476,9 +495,9 @@ DSAStackTy::DSAVarData DSAStackTy::getDS return getDSA(std::next(Iter), D); } -DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) { +Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { assert(Stack.size() > 1 && "Data sharing attributes stack is empty"); - D = D->getCanonicalDecl(); + D = getCanonicalDecl(D); auto It = Stack.back().AlignedMap.find(D); if (It == Stack.back().AlignedMap.end()) { assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); @@ -491,27 +510,27 @@ DeclRefExpr *DSAStackTy::addUniqueAligne return nullptr; } -void DSAStackTy::addLoopControlVariable(VarDecl *D) { +void DSAStackTy::addLoopControlVariable(ValueDecl *D) { assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); - D = D->getCanonicalDecl(); + D = getCanonicalDecl(D); Stack.back().LCVMap.insert(std::make_pair(D, Stack.back().LCVMap.size() + 1)); } -unsigned DSAStackTy::isLoopControlVariable(VarDecl *D) { +unsigned DSAStackTy::isLoopControlVariable(ValueDecl *D) { assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); - D = D->getCanonicalDecl(); + D = getCanonicalDecl(D); return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D] : 0; } -unsigned DSAStackTy::isParentLoopControlVariable(VarDecl *D) { +unsigned DSAStackTy::isParentLoopControlVariable(ValueDecl *D) { assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); - D = D->getCanonicalDecl(); + D = getCanonicalDecl(D); return Stack[Stack.size() - 2].LCVMap.count(D) > 0 ? Stack[Stack.size() - 2].LCVMap[D] : 0; } -VarDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { +ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); if (Stack[Stack.size() - 2].LCVMap.size() < I) return nullptr; @@ -522,8 +541,8 @@ VarDecl *DSAStackTy::getParentLoopContro return nullptr; } -void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) { - D = D->getCanonicalDecl(); +void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A) { + D = getCanonicalDecl(D); if (A == OMPC_threadprivate) { Stack[0].SharingMap[D].Attributes = A; Stack[0].SharingMap[D].RefExpr = E; @@ -581,20 +600,21 @@ static DeclRefExpr *buildDeclRefExpr(Sem VK_LValue); } -DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) { - D = D->getCanonicalDecl(); +DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { + D = getCanonicalDecl(D); DSAVarData DVar; // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced // in a Construct, C/C++, predetermined, p.1] // Variables appearing in threadprivate directives are threadprivate. - if ((D->getTLSKind() != VarDecl::TLS_None && - !(D->hasAttr<OMPThreadPrivateDeclAttr>() && + auto *VD = dyn_cast<VarDecl>(D); + if ((VD && VD->getTLSKind() != VarDecl::TLS_None && + !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && SemaRef.getLangOpts().OpenMPUseTLS && SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || - (D->getStorageClass() == SC_Register && D->hasAttr<AsmLabelAttr>() && - !D->isLocalVarDecl())) { - addDSA(D, buildDeclRefExpr(SemaRef, D, D->getType().getNonReferenceType(), + (VD && VD->getStorageClass() == SC_Register && + VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { + addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()), OMPC_threadprivate); } @@ -611,7 +631,7 @@ DSAStackTy::DSAVarData DSAStackTy::getTo // in a Construct, C/C++, predetermined, p.7] // Variables with static storage duration that are declared in a scope // inside the construct are shared. - if (D->isStaticDataMember()) { + if (VD && VD->isStaticDataMember()) { DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways(), FromParent); if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) @@ -663,8 +683,9 @@ DSAStackTy::DSAVarData DSAStackTy::getTo return DVar; } -DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D, bool FromParent) { - D = D->getCanonicalDecl(); +DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, + bool FromParent) { + D = getCanonicalDecl(D); auto StartI = Stack.rbegin(); auto EndI = std::prev(Stack.rend()); if (FromParent && StartI != EndI) { @@ -674,10 +695,10 @@ DSAStackTy::DSAVarData DSAStackTy::getIm } template <class ClausesPredicate, class DirectivesPredicate> -DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, ClausesPredicate CPred, +DSAStackTy::DSAVarData DSAStackTy::hasDSA(ValueDecl *D, ClausesPredicate CPred, DirectivesPredicate DPred, bool FromParent) { - D = D->getCanonicalDecl(); + D = getCanonicalDecl(D); auto StartI = std::next(Stack.rbegin()); auto EndI = std::prev(Stack.rend()); if (FromParent && StartI != EndI) { @@ -695,9 +716,9 @@ DSAStackTy::DSAVarData DSAStackTy::hasDS template <class ClausesPredicate, class DirectivesPredicate> DSAStackTy::DSAVarData -DSAStackTy::hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, +DSAStackTy::hasInnermostDSA(ValueDecl *D, ClausesPredicate CPred, DirectivesPredicate DPred, bool FromParent) { - D = D->getCanonicalDecl(); + D = getCanonicalDecl(D); auto StartI = std::next(Stack.rbegin()); auto EndI = std::prev(Stack.rend()); if (FromParent && StartI != EndI) { @@ -715,13 +736,13 @@ DSAStackTy::hasInnermostDSA(VarDecl *D, } bool DSAStackTy::hasExplicitDSA( - VarDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, + ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, unsigned Level) { if (CPred(ClauseKindMode)) return true; if (isClauseParsingMode()) ++Level; - D = D->getCanonicalDecl(); + D = getCanonicalDecl(D); auto StartI = Stack.rbegin(); auto EndI = std::prev(Stack.rend()); if (std::distance(StartI, EndI) <= (int)Level) @@ -771,7 +792,7 @@ void Sema::InitDataSharingAttributesStac #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) -bool Sema::IsOpenMPCapturedByRef(VarDecl *VD, +bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, const CapturedRegionScopeInfo *RSI) { assert(LangOpts.OpenMP && "OpenMP is not allowed"); @@ -780,7 +801,7 @@ bool Sema::IsOpenMPCapturedByRef(VarDecl // Find the directive that is associated with the provided scope. auto DKind = DSAStack->getDirectiveForScope(RSI->TheScope); - auto Ty = VD->getType(); + auto Ty = D->getType(); if (isOpenMPTargetDirective(DKind)) { // This table summarizes how a given variable should be passed to the device @@ -853,15 +874,15 @@ bool Sema::IsOpenMPCapturedByRef(VarDecl if (!IsByRef && (Ctx.getTypeSizeInChars(Ty) > Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || - Ctx.getDeclAlign(VD) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) + Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) IsByRef = true; return IsByRef; } -bool Sema::IsOpenMPCapturedVar(VarDecl *VD) { +bool Sema::IsOpenMPCapturedDecl(ValueDecl *D) { assert(LangOpts.OpenMP && "OpenMP is not allowed"); - VD = VD->getCanonicalDecl(); + D = getCanonicalDecl(D); // If we are attempting to capture a global variable in a directive with // 'target' we return true so that this global is also mapped to the device. @@ -870,7 +891,8 @@ bool Sema::IsOpenMPCapturedVar(VarDecl * // then it should not be captured. Therefore, an extra check has to be // inserted here once support for 'declare target' is added. // - if (!VD->hasLocalStorage()) { + auto *VD = dyn_cast<VarDecl>(D); + if (VD && !VD->hasLocalStorage()) { if (DSAStack->getCurrentDirective() == OMPD_target && !DSAStack->isClauseParsingMode()) { return true; @@ -889,32 +911,33 @@ bool Sema::IsOpenMPCapturedVar(VarDecl * if (DSAStack->getCurrentDirective() != OMPD_unknown && (!DSAStack->isClauseParsingMode() || DSAStack->getParentDirective() != OMPD_unknown)) { - if (DSAStack->isLoopControlVariable(VD) || - (VD->hasLocalStorage() && + if (DSAStack->isLoopControlVariable(D) || + (VD && VD->hasLocalStorage() && isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || - DSAStack->isForceVarCapturing()) + (VD && DSAStack->isForceVarCapturing())) return true; - auto DVarPrivate = DSAStack->getTopDSA(VD, DSAStack->isClauseParsingMode()); + auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) return true; - DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), + DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, MatchesAlways(), DSAStack->isClauseParsingMode()); return DVarPrivate.CKind != OMPC_unknown; } return false; } -bool Sema::isOpenMPPrivateVar(VarDecl *VD, unsigned Level) { +bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) { assert(LangOpts.OpenMP && "OpenMP is not allowed"); return DSAStack->hasExplicitDSA( - VD, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level); + D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level); } -bool Sema::isOpenMPTargetCapturedVar(VarDecl *VD, unsigned Level) { +bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { assert(LangOpts.OpenMP && "OpenMP is not allowed"); // Return true if the current level is no longer enclosed in a target region. - return !VD->hasLocalStorage() && + auto *VD = dyn_cast<VarDecl>(D); + return VD && !VD->hasLocalStorage() && DSAStack->hasExplicitDirective(isOpenMPTargetDirective, Level); } @@ -950,9 +973,20 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDi PrivateCopies.push_back(nullptr); continue; } - auto *VD = cast<VarDecl>(cast<DeclRefExpr>(DE)->getDecl()); - QualType Type = VD->getType().getNonReferenceType(); - auto DVar = DSAStack->getTopDSA(VD, false); + DE = DE->IgnoreParens(); + VarDecl *VD = nullptr; + FieldDecl *FD = nullptr; + ValueDecl *D; + if (auto *DRE = dyn_cast<DeclRefExpr>(DE)) { + VD = cast<VarDecl>(DRE->getDecl()); + D = VD; + } else { + assert(isa<MemberExpr>(DE)); + FD = cast<FieldDecl>(cast<MemberExpr>(DE)->getMemberDecl()); + D = FD; + } + QualType Type = D->getType().getNonReferenceType(); + auto DVar = DSAStack->getTopDSA(D, false); if (DVar.CKind == OMPC_lastprivate) { // Generate helper private variable and initialize it with the // default value. The address of the original variable is replaced @@ -961,7 +995,7 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDi // region uses original variable for proper diagnostics. auto *VDPrivate = buildVarDecl( *this, DE->getExprLoc(), Type.getUnqualifiedType(), - VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); + D->getName(), D->hasAttrs() ? &D->getAttrs() : nullptr); ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); if (VDPrivate->isInvalidDecl()) continue; @@ -974,9 +1008,8 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDi } } // Set initializers to private copies if no errors were found. - if (PrivateCopies.size() == Clause->varlist_size()) { + if (PrivateCopies.size() == Clause->varlist_size()) Clause->setPrivateCopies(PrivateCopies); - } } } } @@ -1251,7 +1284,7 @@ Sema::CheckOMPThreadPrivateDecl(SourceLo } static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, - const VarDecl *VD, DSAStackTy::DSAVarData DVar, + const ValueDecl *D, DSAStackTy::DSAVarData DVar, bool IsLoopIterVar = false) { if (DVar.RefExpr) { SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) @@ -1271,7 +1304,8 @@ static void ReportOriginalDSA(Sema &Sema PDSA_Implicit } Reason = PDSA_Implicit; bool ReportHint = false; - auto ReportLoc = VD->getLocation(); + auto ReportLoc = D->getLocation(); + auto *VD = dyn_cast<VarDecl>(D); if (IsLoopIterVar) { if (DVar.CKind == OMPC_private) Reason = PDSA_LoopIterVarPrivate; @@ -1282,15 +1316,15 @@ static void ReportOriginalDSA(Sema &Sema } else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) { Reason = PDSA_TaskVarFirstprivate; ReportLoc = DVar.ImplicitDSALoc; - } else if (VD->isStaticLocal()) + } else if (VD && VD->isStaticLocal()) Reason = PDSA_StaticLocalVarShared; - else if (VD->isStaticDataMember()) + else if (VD && VD->isStaticDataMember()) Reason = PDSA_StaticMemberShared; - else if (VD->isFileVarDecl()) + else if (VD && VD->isFileVarDecl()) Reason = PDSA_GlobalVarShared; - else if (VD->getType().isConstant(SemaRef.getASTContext())) + else if (D->getType().isConstant(SemaRef.getASTContext())) Reason = PDSA_ConstVarShared; - else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { + else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { ReportHint = true; Reason = PDSA_LocalVarPrivate; } @@ -1311,7 +1345,7 @@ class DSAAttrChecker : public StmtVisito bool ErrorFound; CapturedStmt *CS; llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; - llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA; + llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; public: void VisitDeclRefExpr(DeclRefExpr *E) { @@ -1361,6 +1395,44 @@ public: ImplicitFirstprivate.push_back(E); } } + void VisitMemberExpr(MemberExpr *E) { + if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { + if (auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) { + auto DVar = Stack->getTopDSA(FD, false); + // Check if the variable has explicit DSA set and stop analysis if it + // so. + if (DVar.RefExpr) + return; + + auto ELoc = E->getExprLoc(); + auto DKind = Stack->getCurrentDirective(); + // OpenMP [2.9.3.6, Restrictions, p.2] + // A list item that appears in a reduction clause of the innermost + // enclosing worksharing or parallel construct may not be accessed in + // an + // explicit task. + DVar = + Stack->hasInnermostDSA(FD, MatchesAnyClause(OMPC_reduction), + [](OpenMPDirectiveKind K) -> bool { + return isOpenMPParallelDirective(K) || + isOpenMPWorksharingDirective(K) || + isOpenMPTeamsDirective(K); + }, + false); + if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) { + ErrorFound = true; + SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); + ReportOriginalDSA(SemaRef, Stack, FD, DVar); + return; + } + + // Define implicit data-sharing attributes for task. + DVar = Stack->getImplicitDSA(FD, false); + if (DKind == OMPD_task && DVar.CKind != OMPC_shared) + ImplicitFirstprivate.push_back(E); + } + } + } void VisitOMPExecutableDirective(OMPExecutableDirective *S) { for (auto *C : S->clauses()) { // Skip analysis of arguments of implicitly defined firstprivate clause @@ -1381,7 +1453,7 @@ public: bool isErrorFound() { return ErrorFound; } ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; } - llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() { + llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() { return VarsWithInheritedDSA; } @@ -2625,7 +2697,7 @@ StmtResult Sema::ActOnOpenMPExecutableDi return StmtError(); llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; - llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA; + llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; bool ErrorFound = false; ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); if (AStmt) { @@ -3546,7 +3618,7 @@ static bool CheckOpenMPIterationSpace( OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace) { // OpenMP [2.6, Canonical Loop Form] // for (init-expr; test-expr; incr-expr) structured-block @@ -3799,7 +3871,7 @@ static unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built) { unsigned NestedLoopCount = 1; if (CollapseLoopCountExpr) { @@ -4239,7 +4311,7 @@ static bool checkSimdlenSafelenValues(Se StmtResult Sema::ActOnOpenMPSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { if (!AStmt) return StmtError(); @@ -4292,7 +4364,7 @@ StmtResult Sema::ActOnOpenMPSimdDirectiv StmtResult Sema::ActOnOpenMPForDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { if (!AStmt) return StmtError(); @@ -4327,7 +4399,7 @@ StmtResult Sema::ActOnOpenMPForDirective StmtResult Sema::ActOnOpenMPForSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { if (!AStmt) return StmtError(); @@ -4536,7 +4608,7 @@ StmtResult Sema::ActOnOpenMPCriticalDire StmtResult Sema::ActOnOpenMPParallelForDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { if (!AStmt) return StmtError(); @@ -4580,7 +4652,7 @@ StmtResult Sema::ActOnOpenMPParallelForD StmtResult Sema::ActOnOpenMPParallelForSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { if (!AStmt) return StmtError(); @@ -5674,7 +5746,7 @@ static bool checkGrainsizeNumTasksClause StmtResult Sema::ActOnOpenMPTaskLoopDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { if (!AStmt) return StmtError(); @@ -5706,7 +5778,7 @@ StmtResult Sema::ActOnOpenMPTaskLoopDire StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { if (!AStmt) return StmtError(); @@ -5738,7 +5810,7 @@ StmtResult Sema::ActOnOpenMPTaskLoopSimd StmtResult Sema::ActOnOpenMPDistributeDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { if (!AStmt) return StmtError(); @@ -6604,7 +6676,8 @@ OMPClause *Sema::ActOnOpenMPPrivateClaus SmallVector<Expr *, 8> PrivateCopies; for (auto &RefExpr : VarList) { assert(RefExpr && "NULL expr in OpenMP private clause."); - if (isa<DependentScopeDeclRefExpr>(RefExpr)) { + if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || + RefExpr->containsUnexpandedParameterPack()) { // It will be analyzed later. Vars.push_back(RefExpr); PrivateCopies.push_back(nullptr); @@ -6617,29 +6690,26 @@ OMPClause *Sema::ActOnOpenMPPrivateClaus // OpenMP [2.9.3.3, Restrictions, p.1] // A variable that is part of another variable (as an array or // structure element) cannot appear in a private clause. - DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); - if (!DE || !isa<VarDecl>(DE->getDecl())) { - Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); - continue; - } - Decl *D = DE->getDecl(); - VarDecl *VD = cast<VarDecl>(D); - - QualType Type = VD->getType(); - if (Type->isDependentType() || Type->isInstantiationDependentType()) { - // It will be analyzed later. - Vars.push_back(DE); - PrivateCopies.push_back(nullptr); + auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr->IgnoreParens()); + auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr->IgnoreParens()); + if ((!DE || !isa<VarDecl>(DE->getDecl())) && + (getCurrentThisType().isNull() || !ME || + !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || + !isa<FieldDecl>(ME->getMemberDecl()))) { + Diag(ELoc, diag::err_omp_expected_var_name_member_expr) + << (getCurrentThisType().isNull() ? 0 : 1) + << RefExpr->getSourceRange(); continue; } + ValueDecl *D = DE ? DE->getDecl() : ME->getMemberDecl(); + QualType Type = D->getType(); + auto *VD = dyn_cast<VarDecl>(D); // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] // A variable that appears in a private clause must not have an incomplete // type or a reference type. - if (RequireCompleteType(ELoc, Type, - diag::err_omp_private_incomplete_type)) { + if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) continue; - } Type = Type.getNonReferenceType(); // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced @@ -6649,11 +6719,11 @@ OMPClause *Sema::ActOnOpenMPPrivateClaus // listed below. For these exceptions only, listing a predetermined // variable in a data-sharing attribute clause is allowed and overrides // the variable's predetermined data-sharing attributes. - DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); + DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) << getOpenMPClauseName(OMPC_private); - ReportOriginalDSA(*this, DSAStack, VD, DVar); + ReportOriginalDSA(*this, DSAStack, D, DVar); continue; } @@ -6664,10 +6734,11 @@ OMPClause *Sema::ActOnOpenMPPrivateClaus << getOpenMPClauseName(OMPC_private) << Type << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); bool IsDecl = + !VD || VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; - Diag(VD->getLocation(), + Diag(D->getLocation(), IsDecl ? diag::note_previous_decl : diag::note_defined_here) - << VD; + << D; continue; } @@ -6681,16 +6752,16 @@ OMPClause *Sema::ActOnOpenMPPrivateClaus // IdResolver, so the code in the OpenMP region uses original variable for // proper diagnostics. Type = Type.getUnqualifiedType(); - auto VDPrivate = buildVarDecl(*this, DE->getExprLoc(), Type, VD->getName(), - VD->hasAttrs() ? &VD->getAttrs() : nullptr); + auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), + D->hasAttrs() ? &D->getAttrs() : nullptr); ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); if (VDPrivate->isInvalidDecl()) continue; auto VDPrivateRefExpr = buildDeclRefExpr( - *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc()); + *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); - DSAStack->addDSA(VD, DE, OMPC_private); - Vars.push_back(DE); + DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private); + Vars.push_back(RefExpr->IgnoreParens()); PrivateCopies.push_back(VDPrivateRefExpr); } @@ -6754,7 +6825,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivate // structure element) cannot appear in a private clause. DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); if (!DE || !isa<VarDecl>(DE->getDecl())) { - Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); + Diag(ELoc, diag::err_omp_expected_var_name_member_expr) + << 0 << RefExpr->getSourceRange(); continue; } Decl *D = DE->getDecl(); @@ -7017,7 +7089,8 @@ OMPClause *Sema::ActOnOpenMPLastprivateC // element) cannot appear in a lastprivate clause. DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); if (!DE || !isa<VarDecl>(DE->getDecl())) { - Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); + Diag(ELoc, diag::err_omp_expected_var_name_member_expr) + << 0 << RefExpr->getSourceRange(); continue; } Decl *D = DE->getDecl(); @@ -7156,7 +7229,8 @@ OMPClause *Sema::ActOnOpenMPSharedClause // of a C++ class. DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); if (!DE || !isa<VarDecl>(DE->getDecl())) { - Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); + Diag(ELoc, diag::err_omp_expected_var_name_member_expr) + << 0 << RefExpr->getSourceRange(); continue; } Decl *D = DE->getDecl(); @@ -7372,7 +7446,8 @@ OMPClause *Sema::ActOnOpenMPReductionCla auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr); auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr); if (!ASE && !OASE && (!DE || !isa<VarDecl>(DE->getDecl()))) { - Diag(ELoc, diag::err_omp_expected_var_name_or_array_item) << ERange; + Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item) + << 0 << ERange; continue; } QualType Type; @@ -7766,7 +7841,8 @@ OMPClause *Sema::ActOnOpenMPLinearClause // structure element) cannot appear in a private clause. DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); if (!DE || !isa<VarDecl>(DE->getDecl())) { - Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); + Diag(ELoc, diag::err_omp_expected_var_name_member_expr) + << 0 << RefExpr->getSourceRange(); continue; } @@ -7974,7 +8050,8 @@ OMPClause *Sema::ActOnOpenMPAlignedClaus // A list item is a variable name. DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); if (!DE || !isa<VarDecl>(DE->getDecl())) { - Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); + Diag(ELoc, diag::err_omp_expected_var_name_member_expr) + << 0 << RefExpr->getSourceRange(); continue; } @@ -8000,7 +8077,7 @@ OMPClause *Sema::ActOnOpenMPAlignedClaus // OpenMP [2.8.1, simd construct, Restrictions] // A list-item cannot appear in more than one aligned clause. - if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) { + if (Expr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) { Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange(); Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) << getOpenMPClauseName(OMPC_aligned); @@ -8055,7 +8132,8 @@ OMPClause *Sema::ActOnOpenMPCopyinClause // A list item that appears in a copyin clause must be threadprivate. DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); if (!DE || !isa<VarDecl>(DE->getDecl())) { - Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); + Diag(ELoc, diag::err_omp_expected_var_name_member_expr) + << 0 << RefExpr->getSourceRange(); continue; } @@ -8147,7 +8225,8 @@ OMPClause *Sema::ActOnOpenMPCopyprivateC // A list item that appears in a copyin clause must be threadprivate. DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); if (!DE || !isa<VarDecl>(DE->getDecl())) { - Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); + Diag(ELoc, diag::err_omp_expected_var_name_member_expr) + << 0 << RefExpr->getSourceRange(); continue; } @@ -8380,8 +8459,8 @@ Sema::ActOnOpenMPDependClause(OpenMPDepe (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) || (ASE && !ASE->getBase()->getType()->isAnyPointerType() && !ASE->getBase()->getType()->isArrayType())) { - Diag(ELoc, diag::err_omp_expected_var_name_or_array_item) - << RefExpr->getSourceRange(); + Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item) + << 0 << RefExpr->getSourceRange(); continue; } } @@ -8517,8 +8596,8 @@ Sema::ActOnOpenMPMapClause(OpenMPMapClau (DE && !isa<VarDecl>(DE->getDecl())) || (ASE && !ASE->getBase()->getType()->isAnyPointerType() && !ASE->getBase()->getType()->isArrayType())) { - Diag(ELoc, diag::err_omp_expected_var_name_or_array_item) - << RE->getSourceRange(); + Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item) + << 0 << RE->getSourceRange(); continue; } Modified: cfe/trunk/test/OpenMP/distribute_ast_print.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/distribute_ast_print.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/distribute_ast_print.cpp (original) +++ cfe/trunk/test/OpenMP/distribute_ast_print.cpp Wed Jan 20 03:07:54 2016 @@ -8,6 +8,75 @@ void foo() {} +struct S { + S(): a(0) {} + S(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp target +#pragma omp teams +#pragma omp distribute private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(this->S::a) +// CHECK: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) + +class S8 : public S7<S> { + S8() {} + +public: + S8(int v) : S7<S>(v){ +#pragma omp target +#pragma omp teams +#pragma omp distribute private(a) private(this->a) private(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp target +#pragma omp teams +#pragma omp distribute private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) private(this->S7<S>::a) +// CHECK: #pragma omp target +// CHECK-NEXT: #pragma omp teams +// CHECK-NEXT: #pragma omp distribute private(this->a) private(this->a) + template <class T, int N> T tmain(T argc) { T b = argc, c, d, e, f, g; Modified: cfe/trunk/test/OpenMP/for_ast_print.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_ast_print.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/for_ast_print.cpp (original) +++ cfe/trunk/test/OpenMP/for_ast_print.cpp Wed Jan 20 03:07:54 2016 @@ -8,6 +8,57 @@ void foo() {} +struct S { + S(): a(0) {} + S(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp for private(this->a) private(this->a) private(this->S::a) +// CHECK: #pragma omp for private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp for private(this->a) private(this->a) + +class S8 : public S7<S> { + S8() {} + +public: + S8(int v) : S7<S>(v){ +#pragma omp for private(a) private(this->a) private(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp for private(this->a) private(this->a) private(this->S7<S>::a) +// CHECK: #pragma omp for private(this->a) private(this->a) + template <class T, int N> T tmain(T argc) { T b = argc, c, d, e, f, g; Modified: cfe/trunk/test/OpenMP/for_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_private_messages.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/for_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/for_private_messages.cpp Wed Jan 20 03:07:54 2016 @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp for private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -126,6 +174,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp for private // expected-error {{expected '(' after 'private'}} @@ -190,6 +240,8 @@ int main(int argc, char **argv) { for(int k = 0; k < argc; ++k) si = k + 1; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } Modified: cfe/trunk/test/OpenMP/for_simd_ast_print.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_simd_ast_print.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/for_simd_ast_print.cpp (original) +++ cfe/trunk/test/OpenMP/for_simd_ast_print.cpp Wed Jan 20 03:07:54 2016 @@ -6,6 +6,57 @@ #ifndef HEADER #define HEADER +struct S1 { + S1(): a(0) {} + S1(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp for simd private(this->a) private(this->a) private(this->S1::a) +// CHECK: #pragma omp for simd private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp for simd private(this->a) private(this->a) + +class S8 : public S7<S1> { + S8() {} + +public: + S8(int v) : S7<S1>(v){ +#pragma omp for simd private(a) private(this->a) private(S7<S1>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp for simd private(this->a) private(this->a) private(this->S7<S1>::a) +// CHECK: #pragma omp for simd private(this->a) private(this->a) + void foo() {} int g_ind = 1; template<class T, class N> T reduct(T* arr, N num) { Modified: cfe/trunk/test/OpenMP/for_simd_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_simd_private_messages.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/for_simd_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/for_simd_private_messages.cpp Wed Jan 20 03:07:54 2016 @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp for simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -119,6 +167,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp for simd private // expected-error {{expected '(' after 'private'}} @@ -180,6 +230,8 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) m = k + 2; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } Modified: cfe/trunk/test/OpenMP/parallel_ast_print.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_ast_print.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/parallel_ast_print.cpp (original) +++ cfe/trunk/test/OpenMP/parallel_ast_print.cpp Wed Jan 20 03:07:54 2016 @@ -8,6 +8,57 @@ void foo() {} +struct S1 { + S1(): a(0) {} + S1(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp parallel private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp parallel private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel private(this->a) private(this->a) private(this->S1::a) +// CHECK: #pragma omp parallel private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp parallel private(this->a) private(this->a) + +class S8 : public S7<S1> { + S8() {} + +public: + S8(int v) : S7<S1>(v){ +#pragma omp parallel private(a) private(this->a) private(S7<S1>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp parallel private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel private(this->a) private(this->a) private(this->S7<S1>::a) +// CHECK: #pragma omp parallel private(this->a) private(this->a) + template <class T> struct S { operator T() {return T();} Modified: cfe/trunk/test/OpenMP/parallel_for_ast_print.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_ast_print.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/parallel_for_ast_print.cpp (original) +++ cfe/trunk/test/OpenMP/parallel_for_ast_print.cpp Wed Jan 20 03:07:54 2016 @@ -8,6 +8,57 @@ void foo() {} +struct S { + S(): a(0) {} + S(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp parallel for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp parallel for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel for private(this->a) private(this->a) private(this->S::a) +// CHECK: #pragma omp parallel for private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp parallel for private(this->a) private(this->a) + +class S8 : public S7<S> { + S8() {} + +public: + S8(int v) : S7<S>(v){ +#pragma omp parallel for private(a) private(this->a) private(S7<S>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp parallel for private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel for private(this->a) private(this->a) private(this->S7<S>::a) +// CHECK: #pragma omp parallel for private(this->a) private(this->a) + template <class T, int N> T tmain(T argc) { T b = argc, c, d, e, f, h; Modified: cfe/trunk/test/OpenMP/parallel_for_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_private_messages.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/parallel_for_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/parallel_for_private_messages.cpp Wed Jan 20 03:07:54 2016 @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp parallel for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp parallel for private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp parallel for private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp parallel for private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp parallel for private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -119,6 +167,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp parallel for private // expected-error {{expected '(' after 'private'}} @@ -180,6 +230,8 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) m = k + 2; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } Modified: cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp (original) +++ cfe/trunk/test/OpenMP/parallel_for_simd_ast_print.cpp Wed Jan 20 03:07:54 2016 @@ -7,6 +7,58 @@ #define HEADER void foo() {} + +struct S1 { + S1() : a(0) {} + S1(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp parallel for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp parallel for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(this->S1::a) +// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) + +class S8 : public S7<S1> { + S8() {} + +public: + S8(int v) : S7<S1>(v){ +#pragma omp parallel for simd private(a) private(this->a) private(S7<S1>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp parallel for simd private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) private(this->S7<S1>::a) +// CHECK: #pragma omp parallel for simd private(this->a) private(this->a) + int g_ind = 1; template<class T, class N> T reduct(T* arr, N num) { N i; Modified: cfe/trunk/test/OpenMP/parallel_for_simd_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_simd_private_messages.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/parallel_for_simd_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/parallel_for_simd_private_messages.cpp Wed Jan 20 03:07:54 2016 @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp parallel for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp parallel for simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp parallel for simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp parallel for simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp parallel for simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -119,6 +167,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp parallel for simd private // expected-error {{expected '(' after 'private'}} @@ -180,6 +230,8 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) m = k + 3; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } Modified: cfe/trunk/test/OpenMP/parallel_sections_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_sections_private_messages.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/parallel_sections_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/parallel_sections_private_messages.cpp Wed Jan 20 03:07:54 2016 @@ -29,7 +29,13 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp parallel sections private(a) private(this->a) + { + for (int k = 0; k < v; ++k) + ++this->a; + } + } }; class S5 { int a; @@ -37,6 +43,60 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp parallel sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a; ++k) + ++s.a; + } + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp parallel sections private(a) private(this->a) + { + for (int k = 0; k < v; ++k) + ++this->a; + } + } + S6 &operator=(S6 &s) { +#pragma omp parallel sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a; ++k) + ++s.a; + } + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp parallel sections private(a) private(this->a) private(T::a) + { + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + } + S7 &operator=(S7 &s) { +#pragma omp parallel sections private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + } + return *this; + } }; S3 h; @@ -134,6 +194,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp parallel sections private // expected-error {{expected '(' after 'private'}} @@ -212,6 +274,8 @@ int main(int argc, char **argv) { foo(); } - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } Modified: cfe/trunk/test/OpenMP/sections_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/sections_private_messages.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/sections_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/sections_private_messages.cpp Wed Jan 20 03:07:54 2016 @@ -29,7 +29,13 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp sections private(a) private(this->a) + { + for (int k = 0; k < v; ++k) + ++this->a; + } + } }; class S5 { int a; @@ -37,6 +43,60 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a; ++k) + ++s.a; + } + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp sections private(a) private(this->a) + { + for (int k = 0; k < v; ++k) + ++this->a; + } + } + S6 &operator=(S6 &s) { +#pragma omp sections private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a; ++k) + ++s.a; + } + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp sections private(a) private(this->a) private(T::a) + { + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + } + S7 &operator=(S7 &s) { +#pragma omp sections private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + { + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + } + return *this; + } }; S3 h; @@ -134,6 +194,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp sections private // expected-error {{expected '(' after 'private'}} @@ -212,6 +274,8 @@ int main(int argc, char **argv) { foo(); } - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } Modified: cfe/trunk/test/OpenMP/simd_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/simd_private_messages.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/simd_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/simd_private_messages.cpp Wed Jan 20 03:07:54 2016 @@ -26,13 +26,61 @@ class S4 { int a; S4(); // expected-note {{implicitly declared private here}} public: - S4(int v):a(v) { } + S4(int v) : a(v) { +#pragma omp simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; S5():a(0) {} // expected-note {{implicitly declared private here}} public: S5(int v):a(v) { } + S5 &operator=(S5 &s) { +#pragma omp simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -96,6 +144,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp simd private // expected-error {{expected '(' after 'private'}} @@ -137,6 +187,8 @@ int main(int argc, char **argv) { #pragma omp simd private(i) for (int k = 0; k < argc; ++k) ++k; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } Modified: cfe/trunk/test/OpenMP/single_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/single_private_messages.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/single_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/single_private_messages.cpp Wed Jan 20 03:07:54 2016 @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp single private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp single private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp single private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp single private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp single private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp single private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -102,6 +150,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp single private // expected-error {{expected '(' after 'private'}} @@ -146,6 +196,8 @@ int main(int argc, char **argv) { #pragma omp single private(m) // OK foo(); - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } Modified: cfe/trunk/test/OpenMP/target_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_private_messages.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/target_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/target_private_messages.cpp Wed Jan 20 03:07:54 2016 @@ -22,7 +22,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp target private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -30,6 +34,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp target private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp target private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp target private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp target private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp target private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -86,6 +134,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp target private // expected-error {{expected '(' after 'private'}} @@ -116,6 +166,8 @@ int main(int argc, char **argv) { static int si; #pragma omp target private(si) // OK {} - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } Modified: cfe/trunk/test/OpenMP/task_ast_print.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/task_ast_print.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/task_ast_print.cpp (original) +++ cfe/trunk/test/OpenMP/task_ast_print.cpp Wed Jan 20 03:07:54 2016 @@ -8,6 +8,57 @@ void foo() {} +struct S1 { + S1(): a(0) {} + S1(int v) : a(v) {} + int a; + typedef int type; +}; + +template <typename T> +class S7 : public T { +protected: + T a; + S7() : a(0) {} + +public: + S7(typename T::type v) : a(v) { +#pragma omp task private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp task private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S1::a) +// CHECK: #pragma omp task private(this->a) private(this->a) private(T::a) +// CHECK: #pragma omp task private(this->a) private(this->a) + +class S8 : public S7<S1> { + S8() {} + +public: + S8(int v) : S7<S1>(v){ +#pragma omp task private(a) private(this->a) private(S7<S1>::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S8 &operator=(S8 &s) { +#pragma omp task private(a) private(this->a) + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } +}; + +// CHECK: #pragma omp task private(this->a) private(this->a) private(this->S7<S1>::a) +// CHECK: #pragma omp task private(this->a) private(this->a) + template <class T> struct S { operator T() { return T(); } Modified: cfe/trunk/test/OpenMP/taskloop_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/taskloop_private_messages.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/taskloop_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/taskloop_private_messages.cpp Wed Jan 20 03:07:54 2016 @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp taskloop private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp taskloop private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp taskloop private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp taskloop private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp taskloop private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp taskloop private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -126,6 +174,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp taskloop private // expected-error {{expected '(' after 'private'}} @@ -190,6 +240,8 @@ int main(int argc, char **argv) { for(int k = 0; k < argc; ++k) si = k + 1; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } Modified: cfe/trunk/test/OpenMP/taskloop_simd_private_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/taskloop_simd_private_messages.cpp?rev=258299&r1=258298&r2=258299&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/taskloop_simd_private_messages.cpp (original) +++ cfe/trunk/test/OpenMP/taskloop_simd_private_messages.cpp Wed Jan 20 03:07:54 2016 @@ -29,7 +29,11 @@ class S4 { S4(); // expected-note {{implicitly declared private here}} public: - S4(int v) : a(v) {} + S4(int v) : a(v) { +#pragma omp taskloop simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } }; class S5 { int a; @@ -37,6 +41,50 @@ class S5 { public: S5(int v) : a(v) {} + S5 &operator=(S5 &s) { +#pragma omp taskloop simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S6 { +public: + T a; + + S6() : a(0) {} + S6(T v) : a(v) { +#pragma omp taskloop simd private(a) private(this->a) + for (int k = 0; k < v; ++k) + ++this->a; + } + S6 &operator=(S6 &s) { +#pragma omp taskloop simd private(a) private(this->a) private(s.a) // expected-error {{expected variable name or data member of current class}} + for (int k = 0; k < s.a; ++k) + ++s.a; + return *this; + } +}; + +template <typename T> +class S7 : public T { + T a; + S7() : a(0) {} + +public: + S7(T v) : a(v) { +#pragma omp taskloop simd private(a) private(this->a) private(T::a) + for (int k = 0; k < a.a; ++k) + ++this->a.a; + } + S7 &operator=(S7 &s) { +#pragma omp taskloop simd private(a) private(this->a) private(s.a) private(s.T::a) // expected-error 2 {{expected variable name or data member of current class}} + for (int k = 0; k < s.a.a; ++k) + ++s.a.a; + return *this; + } }; S3 h; @@ -126,6 +174,8 @@ using A::x; int main(int argc, char **argv) { S4 e(4); S5 g(5); + S6<float> s6(0.0) , s6_0(1.0); + S7<S6<float> > s7(0.0) , s7_0(1.0); int i; int &j = i; #pragma omp taskloop simd private // expected-error {{expected '(' after 'private'}} @@ -190,6 +240,8 @@ int main(int argc, char **argv) { for(int k = 0; k < argc; ++k) si = k + 1; - return 0; + s6 = s6_0; // expected-note {{in instantiation of member function 'S6<float>::operator=' requested here}} + s7 = s7_0; // expected-note {{in instantiation of member function 'S7<S6<float> >::operator=' requested here}} + return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits