Author: abataev Date: Thu Aug 20 05:54:39 2015 New Revision: 245550 URL: http://llvm.org/viewvc/llvm-project?rev=245550&view=rev Log: [OPENMP 4.1] Initial support for modifiers in 'linear' clause.
OpenMP 4.1 adds 3 optional modifiers to 'linear' clause. Format of 'linear' clause has changed to: ``` linear(linear-list[ : linear-step]) ``` where linear-list is one of the following ``` list modifier(list) ``` where modifier is one of the following: ``` ref (C++) val (C/C++) uval (C++) ``` Patch adds parsing and sema analysis for these modifiers. Modified: cfe/trunk/include/clang/AST/OpenMPClause.h cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Basic/OpenMPKinds.def cfe/trunk/include/clang/Basic/OpenMPKinds.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/AST/Stmt.cpp cfe/trunk/lib/AST/StmtPrinter.cpp cfe/trunk/lib/Basic/OpenMPKinds.cpp cfe/trunk/lib/Parse/ParseOpenMP.cpp cfe/trunk/lib/Sema/SemaOpenMP.cpp cfe/trunk/lib/Sema/TreeTransform.h cfe/trunk/lib/Serialization/ASTReaderStmt.cpp cfe/trunk/lib/Serialization/ASTWriterStmt.cpp cfe/trunk/test/OpenMP/simd_linear_messages.cpp cfe/trunk/test/OpenMP/simd_misc_messages.c Modified: cfe/trunk/include/clang/AST/OpenMPClause.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/OpenMPClause.h (original) +++ cfe/trunk/include/clang/AST/OpenMPClause.h Thu Aug 20 05:54:39 2015 @@ -1641,6 +1641,10 @@ public: /// class OMPLinearClause : public OMPVarListClause<OMPLinearClause> { friend class OMPClauseReader; + /// \brief Modifier of 'linear' clause. + OpenMPLinearClauseKind Modifier; + /// \brief Location of linear modifier if any. + SourceLocation ModifierLoc; /// \brief Location of ':'. SourceLocation ColonLoc; @@ -1659,11 +1663,12 @@ class OMPLinearClause : public OMPVarLis /// \param NumVars Number of variables. /// OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc, + OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) : OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc, EndLoc, NumVars), - ColonLoc(ColonLoc) {} + Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} /// \brief Build an empty clause. /// @@ -1673,7 +1678,7 @@ class OMPLinearClause : public OMPVarLis : OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(), SourceLocation(), SourceLocation(), NumVars), - ColonLoc(SourceLocation()) {} + Modifier(OMPC_LINEAR_val), ModifierLoc(), ColonLoc() {} /// \brief Gets the list of initial values for linear variables. /// @@ -1733,6 +1738,8 @@ public: /// \param C AST Context. /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. + /// \param Modifier Modifier of 'linear' clause. + /// \param ModifierLoc Modifier location. /// \param ColonLoc Location of ':'. /// \param EndLoc Ending location of the clause. /// \param VL List of references to the variables. @@ -1742,6 +1749,7 @@ public: /// \param CalcStep Calculation of the linear step. static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep); @@ -1752,9 +1760,19 @@ public: /// static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars); + /// \brief Set modifier. + void setModifier(OpenMPLinearClauseKind Kind) { Modifier = Kind; } + /// \brief Return modifier. + OpenMPLinearClauseKind getModifier() const { return Modifier; } + + /// \brief Set modifier location. + void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } + /// \brief Return modifier location. + SourceLocation getModifierLoc() const { return ModifierLoc; } + /// \brief Sets the location of ':'. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } - /// \brief Returns the location of '('. + /// \brief Returns the location of ':'. SourceLocation getColonLoc() const { return ColonLoc; } /// \brief Returns linear step. Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Aug 20 05:54:39 2015 @@ -7667,6 +7667,8 @@ def err_omp_parent_cancel_region_nowait "parent region for 'omp %select{cancellation point/cancel}0' construct cannot be nowait">; def err_omp_parent_cancel_region_ordered : Error< "parent region for 'omp %select{cancellation point/cancel}0' construct cannot be ordered">; +def err_omp_wrong_linear_modifier : Error< + "expected %select{'val' modifier|one of 'ref', val' or 'uval' modifiers}0">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original) +++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Thu Aug 20 05:54:39 2015 @@ -75,6 +75,9 @@ #ifndef OPENMP_DEPEND_KIND #define OPENMP_DEPEND_KIND(Name) #endif +#ifndef OPENMP_LINEAR_KIND +#define OPENMP_LINEAR_KIND(Name) +#endif // OpenMP directives. OPENMP_DIRECTIVE(threadprivate) @@ -212,6 +215,11 @@ OPENMP_DEPEND_KIND(in) OPENMP_DEPEND_KIND(out) OPENMP_DEPEND_KIND(inout) +// Modifiers for 'linear' clause. +OPENMP_LINEAR_KIND(val) +OPENMP_LINEAR_KIND(ref) +OPENMP_LINEAR_KIND(uval) + // Clauses allowed for OpenMP directive 'parallel for'. OPENMP_PARALLEL_FOR_CLAUSE(if) OPENMP_PARALLEL_FOR_CLAUSE(num_threads) @@ -293,6 +301,7 @@ OPENMP_TEAMS_CLAUSE(firstprivate) OPENMP_TEAMS_CLAUSE(shared) OPENMP_TEAMS_CLAUSE(reduction) +#undef OPENMP_LINEAR_KIND #undef OPENMP_DEPEND_KIND #undef OPENMP_SCHEDULE_KIND #undef OPENMP_PROC_BIND_KIND Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.h?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/OpenMPKinds.h (original) +++ cfe/trunk/include/clang/Basic/OpenMPKinds.h Thu Aug 20 05:54:39 2015 @@ -70,6 +70,14 @@ enum OpenMPDependClauseKind { OMPC_DEPEND_unknown }; +/// \brief OpenMP attributes for 'linear' clause. +enum OpenMPLinearClauseKind { +#define OPENMP_LINEAR_KIND(Name) \ + OMPC_LINEAR_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_LINEAR_unknown +}; + OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str); const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind); Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Thu Aug 20 05:54:39 2015 @@ -7972,7 +7972,7 @@ public: SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, - SourceLocation DepLoc); + OpenMPLinearClauseKind LinKind, SourceLocation DepLinLoc); /// \brief Called on well-formed 'private' clause. OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, @@ -8001,12 +8001,11 @@ public: CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId); /// \brief Called on well-formed 'linear' clause. - OMPClause *ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, - Expr *Step, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation ColonLoc, - SourceLocation EndLoc); + OMPClause * + ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, + SourceLocation StartLoc, SourceLocation LParenLoc, + OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, + SourceLocation ColonLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'aligned' clause. OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment, Modified: cfe/trunk/lib/AST/Stmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/lib/AST/Stmt.cpp (original) +++ cfe/trunk/lib/AST/Stmt.cpp Thu Aug 20 05:54:39 2015 @@ -1343,6 +1343,7 @@ void OMPLinearClause::setFinals(ArrayRef OMPLinearClause *OMPLinearClause::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep) { // Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions @@ -1350,8 +1351,8 @@ OMPLinearClause *OMPLinearClause::Create void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause), llvm::alignOf<Expr *>()) + (5 * VL.size() + 2) * sizeof(Expr *)); - OMPLinearClause *Clause = new (Mem) - OMPLinearClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size()); + OMPLinearClause *Clause = new (Mem) OMPLinearClause( + StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc, EndLoc, VL.size()); Clause->setVarRefs(VL); Clause->setPrivates(PL); Clause->setInits(IL); Modified: cfe/trunk/lib/AST/StmtPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/lib/AST/StmtPrinter.cpp (original) +++ cfe/trunk/lib/AST/StmtPrinter.cpp Thu Aug 20 05:54:39 2015 @@ -767,7 +767,13 @@ void OMPClausePrinter::VisitOMPReduction void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) { if (!Node->varlist_empty()) { OS << "linear"; + if (Node->getModifierLoc().isValid()) { + OS << '(' + << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier()); + } VisitOMPClauseList(Node, '('); + if (Node->getModifierLoc().isValid()) + OS << ')'; if (Node->getStep() != nullptr) { OS << ": "; Node->getStep()->printPretty(OS, nullptr, Policy, 0); Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original) +++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Thu Aug 20 05:54:39 2015 @@ -96,6 +96,11 @@ unsigned clang::getOpenMPSimpleClauseTyp #define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_DEPEND_unknown); + case OMPC_linear: + return llvm::StringSwitch<OpenMPLinearClauseKind>(Str) +#define OPENMP_LINEAR_KIND(Name) .Case(#Name, OMPC_LINEAR_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_LINEAR_unknown); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -108,7 +113,6 @@ unsigned clang::getOpenMPSimpleClauseTyp case OMPC_lastprivate: case OMPC_shared: case OMPC_reduction: - case OMPC_linear: case OMPC_aligned: case OMPC_copyin: case OMPC_copyprivate: @@ -170,6 +174,16 @@ const char *clang::getOpenMPSimpleClause #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'schedule' clause type"); + case OMPC_linear: + switch (Type) { + case OMPC_LINEAR_unknown: + return "unknown"; +#define OPENMP_LINEAR_KIND(Name) \ + case OMPC_LINEAR_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" + } + llvm_unreachable("Invalid OpenMP 'linear' clause type"); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -182,7 +196,6 @@ const char *clang::getOpenMPSimpleClause case OMPC_lastprivate: case OMPC_shared: case OMPC_reduction: - case OMPC_linear: case OMPC_aligned: case OMPC_copyin: case OMPC_copyprivate: Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original) +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Thu Aug 20 05:54:39 2015 @@ -708,7 +708,7 @@ static bool ParseReductionId(Parser &P, /// shared-clause: /// 'shared' '(' list ')' /// linear-clause: -/// 'linear' '(' list [ ':' linear-step ] ')' +/// 'linear' '(' linear-list [ ':' linear-step ] ')' /// aligned-clause: /// 'aligned' '(' list [ ':' alignment ] ')' /// reduction-clause: @@ -720,6 +720,10 @@ static bool ParseReductionId(Parser &P, /// depend-clause: /// 'depend' '(' in | out | inout : list ')' /// +/// For 'linear' clause linear-list may have the following forms: +/// list +/// modifier(list) +/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++). OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) { SourceLocation Loc = Tok.getLocation(); SourceLocation LOpen = ConsumeToken(); @@ -729,7 +733,10 @@ OMPClause *Parser::ParseOpenMPVarListCla UnqualifiedId ReductionId; bool InvalidReductionId = false; OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown; - SourceLocation DepLoc; + // OpenMP 4.1 [2.15.3.7, linear Clause] + // If no modifier is specified it is assumed to be val. + OpenMPLinearClauseKind LinearModifier = OMPC_LINEAR_val; + SourceLocation DepLinLoc; // Parse '('. BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); @@ -737,6 +744,9 @@ OMPClause *Parser::ParseOpenMPVarListCla getOpenMPClauseName(Kind))) return nullptr; + bool NeedRParenForLinear = false; + BalancedDelimiterTracker LinearT(*this, tok::l_paren, + tok::annot_pragma_openmp_end); // Handle reduction-identifier for reduction clause. if (Kind == OMPC_reduction) { ColonProtectionRAIIObject ColonRAII(*this); @@ -759,7 +769,7 @@ OMPClause *Parser::ParseOpenMPVarListCla ColonProtectionRAIIObject ColonRAII(*this); DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType( Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "")); - DepLoc = Tok.getLocation(); + DepLinLoc = Tok.getLocation(); if (DepKind == OMPC_DEPEND_unknown) { SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, @@ -772,6 +782,16 @@ OMPClause *Parser::ParseOpenMPVarListCla } else { Diag(Tok, diag::warn_pragma_expected_colon) << "dependency type"; } + } else if (Kind == OMPC_linear) { + // Try to parse modifier if any. + if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) { + StringRef TokSpelling = PP.getSpelling(Tok); + LinearModifier = static_cast<OpenMPLinearClauseKind>( + getOpenMPSimpleClauseType(Kind, TokSpelling)); + DepLinLoc = ConsumeToken(); + LinearT.consumeOpen(); + NeedRParenForLinear = true; + } } SmallVector<Expr *, 5> Vars; @@ -804,6 +824,10 @@ OMPClause *Parser::ParseOpenMPVarListCla << (Kind == OMPC_flush); } + // Parse ')' for linear clause with modifier. + if (NeedRParenForLinear) + LinearT.consumeClose(); + // Parse ':' linear-step (or ':' alignment). Expr *TailExpr = nullptr; const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon); @@ -831,6 +855,6 @@ OMPClause *Parser::ParseOpenMPVarListCla ReductionIdScopeSpec, ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId) : DeclarationNameInfo(), - DepKind, DepLoc); + DepKind, LinearModifier, DepLinLoc); } Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Aug 20 05:54:39 2015 @@ -5254,7 +5254,7 @@ OMPClause *Sema::ActOnOpenMPVarListClaus SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, - SourceLocation DepLoc) { + OpenMPLinearClauseKind LinKind, SourceLocation DepLinLoc) { OMPClause *Res = nullptr; switch (Kind) { case OMPC_private: @@ -5275,7 +5275,7 @@ OMPClause *Sema::ActOnOpenMPVarListClaus break; case OMPC_linear: Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, - ColonLoc, EndLoc); + LinKind, DepLinLoc, ColonLoc, EndLoc); break; case OMPC_aligned: Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, @@ -5291,7 +5291,7 @@ OMPClause *Sema::ActOnOpenMPVarListClaus Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); break; case OMPC_depend: - Res = ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, StartLoc, + Res = ActOnOpenMPDependClause(DepKind, DepLinLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); break; case OMPC_if: @@ -6313,14 +6313,18 @@ OMPClause *Sema::ActOnOpenMPReductionCla RHSs, ReductionOps); } -OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation ColonLoc, - SourceLocation EndLoc) { +OMPClause *Sema::ActOnOpenMPLinearClause( + ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, + SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, + SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { SmallVector<Expr *, 8> Vars; SmallVector<Expr *, 8> Privates; SmallVector<Expr *, 8> Inits; + if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || + LinKind == OMPC_LINEAR_unknown) { + Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; + LinKind = OMPC_LINEAR_val; + } for (auto &RefExpr : VarList) { assert(RefExpr && "NULL expr in OpenMP linear clause."); if (isa<DependentScopeDeclRefExpr>(RefExpr)) { @@ -6459,8 +6463,9 @@ OMPClause *Sema::ActOnOpenMPLinearClause } } - return OMPLinearClause::Create(Context, StartLoc, LParenLoc, ColonLoc, EndLoc, - Vars, Privates, Inits, StepExpr, CalcStepExpr); + return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, + ColonLoc, EndLoc, Vars, Privates, Inits, + StepExpr, CalcStepExpr); } static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Modified: cfe/trunk/lib/Sema/TreeTransform.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/lib/Sema/TreeTransform.h (original) +++ cfe/trunk/lib/Sema/TreeTransform.h Thu Aug 20 05:54:39 2015 @@ -1528,10 +1528,13 @@ public: OMPClause *RebuildOMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, + OpenMPLinearClauseKind Modifier, + SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc, - ColonLoc, EndLoc); + Modifier, ModifierLoc, ColonLoc, + EndLoc); } /// \brief Build a new OpenMP 'aligned' clause. @@ -7419,9 +7422,9 @@ TreeTransform<Derived>::TransformOMPLine ExprResult Step = getDerived().TransformExpr(C->getStep()); if (Step.isInvalid()) return nullptr; - return getDerived().RebuildOMPLinearClause(Vars, Step.get(), C->getLocStart(), - C->getLParenLoc(), - C->getColonLoc(), C->getLocEnd()); + return getDerived().RebuildOMPLinearClause( + Vars, Step.get(), C->getLocStart(), C->getLParenLoc(), C->getModifier(), + C->getModifierLoc(), C->getColonLoc(), C->getLocEnd()); } template <typename Derived> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Thu Aug 20 05:54:39 2015 @@ -1970,6 +1970,8 @@ void OMPClauseReader::VisitOMPReductionC void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) { C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); C->setColonLoc(Reader->ReadSourceLocation(Record, Idx)); + C->setModifier(static_cast<OpenMPLinearClauseKind>(Record[Idx++])); + C->setModifierLoc(Reader->ReadSourceLocation(Record, Idx)); unsigned NumVars = C->varlist_size(); SmallVector<Expr *, 16> Vars; Vars.reserve(NumVars); Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Thu Aug 20 05:54:39 2015 @@ -1851,6 +1851,8 @@ void OMPClauseWriter::VisitOMPLinearClau Record.push_back(C->varlist_size()); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); Writer->Writer.AddSourceLocation(C->getColonLoc(), Record); + Record.push_back(C->getModifier()); + Writer->Writer.AddSourceLocation(C->getModifierLoc(), Record); for (auto *VE : C->varlists()) { Writer->Writer.AddStmt(VE); } Modified: cfe/trunk/test/OpenMP/simd_linear_messages.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/simd_linear_messages.cpp?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/simd_linear_messages.cpp (original) +++ cfe/trunk/test/OpenMP/simd_linear_messages.cpp Thu Aug 20 05:54:39 2015 @@ -107,11 +107,21 @@ template<class I, class C> int foomain(I for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (uval( // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (ref() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (foo() // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear () // expected-error {{expected expression}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} + #pragma omp simd linear (val argc // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (val(argc, // expected-error {{expected expression}} expected-error 2 {{expected ')'}} expected-note 2 {{to match this '('}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; @@ -121,15 +131,15 @@ template<class I, class C> int foomain(I for (int k = 0; k < argc; ++k) ++k; // expected-error@+2 {{linear variable with incomplete type 'S1'}} // expected-error@+1 {{const-qualified variable cannot be linear}} - #pragma omp simd linear (a, b:B::ib) + #pragma omp simd linear (val(a, b):B::ib) for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argv[1]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear(e, g) + #pragma omp simd linear(ref(e, g)) for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear(i) + #pragma omp simd linear(uval(i)) for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel { @@ -156,6 +166,20 @@ namespace C { using A::x; } +void linear_modifiers(int argc) { + int f; + #pragma omp simd linear(f) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(val(f)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(uval(f)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(ref(f)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(foo(f)) // expected-error {{expected one of 'ref', val' or 'uval' modifiers}} + for (int k = 0; k < argc; ++k) ++k; +} + int f; int main(int argc, char **argv) { double darr[100]; @@ -176,6 +200,12 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear () // expected-error {{expected expression}} for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (val // expected-error {{use of undeclared identifier 'val'}} expected-error {{expected ')'}} expected-note {{to match this '('}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (ref()) // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear (foo()) // expected-error {{expected expression}} + for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argc // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -194,19 +224,19 @@ int main(int argc, char **argv) { for (int k = 0; k < argc; ++k) ++k; // expected-error@+2 {{argument of a linear clause should be of integral or pointer type, not 'S4'}} // expected-error@+1 {{argument of a linear clause should be of integral or pointer type, not 'S5'}} - #pragma omp simd linear(e, g) + #pragma omp simd linear(val(e, g)) for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear(h, C::x) // expected-error 2 {{threadprivate or thread local variable cannot be linear}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel { int i; - #pragma omp simd linear(i) + #pragma omp simd linear(val(i)) for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear(i : 4) + #pragma omp simd linear(uval(i) : 4) for (int k = 0; k < argc; ++k) { ++k; i += 4; } } - #pragma omp simd linear(j) + #pragma omp simd linear(ref(j)) for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear(i) for (int k = 0; k < argc; ++k) ++k; Modified: cfe/trunk/test/OpenMP/simd_misc_messages.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/simd_misc_messages.c?rev=245550&r1=245549&r2=245550&view=diff ============================================================================== --- cfe/trunk/test/OpenMP/simd_misc_messages.c (original) +++ cfe/trunk/test/OpenMP/simd_misc_messages.c Thu Aug 20 05:54:39 2015 @@ -678,3 +678,17 @@ void test_loop_messages() { } } +void linear_modifiers(int argc) { + int f; + #pragma omp simd linear(f) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(val(f)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(uval(f)) // expected-error {{expected 'val' modifier}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(ref(f)) // expected-error {{expected 'val' modifier}} + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(foo(f)) // expected-error {{expected 'val' modifier}} + for (int k = 0; k < argc; ++k) ++k; +} + _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits