r211007 - [OPENMP] Initial support of 'reduction' clause
Alexey Bataev
a.bataev at hotmail.com
Mon Jun 16 19:40:43 PDT 2014
Alp,
Fixed, thanks for finding!
Best regards,
Alexey Bataev
=============
Software Engineer
Intel Compiler Team
16 Июнь 2014 г. 17:12:28, Alp Toker писал:
>
> On 16/06/2014 10:08, Alexey Bataev wrote:
>> Author: abataev
>> Date: Mon Jun 16 02:08:35 2014
>> New Revision: 211007
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=211007&view=rev
>> Log:
>> [OPENMP] Initial support of 'reduction' clause
>>
>> Added:
>> cfe/trunk/test/OpenMP/parallel_reduction_messages.cpp (with
>> props)
>> Modified:
>> cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
>> cfe/trunk/include/clang/AST/OpenMPClause.h
>> cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> cfe/trunk/include/clang/Basic/OpenMPKinds.def
>> cfe/trunk/include/clang/Sema/Sema.h
>> cfe/trunk/lib/AST/Stmt.cpp
>> cfe/trunk/lib/AST/StmtPrinter.cpp
>> cfe/trunk/lib/AST/StmtProfile.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/parallel_ast_print.cpp
>> cfe/trunk/test/OpenMP/simd_aligned_messages.cpp
>> cfe/trunk/test/OpenMP/simd_linear_messages.cpp
>> cfe/trunk/tools/libclang/CIndex.cpp
>>
>> Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)
>> +++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Mon Jun 16
>> 02:08:35 2014
>> @@ -2391,6 +2391,15 @@ bool RecursiveASTVisitor<Derived>::Visit
>> return true;
>> }
>> +template <typename Derived>
>> +bool DataRecursiveASTVisitor<Derived>::VisitOMPReductionClause(
>> + OMPReductionClause *C) {
>> + TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
>> + TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
>> + VisitOMPClauseList(C);
>> + return true;
>> +}
>> +
>
> This should be just 'RecursiveASTVisitor' like the other definitions
> in that file, not 'DataRecursiveASTVisitor'.
>
> Can you sync this up with the copy in RecursiveASTVisitor.h and
> clang-format both additions so they're in the same position in their
> respective files?
>
> Alp.
>
>
>> // FIXME: look at the following tricky-seeming exprs to see if we
>> // need to recurse on anything. These are ones that have methods
>> // returning decls or qualtypes or nestednamespecifier -- though I'm
>>
>> Modified: cfe/trunk/include/clang/AST/OpenMPClause.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/AST/OpenMPClause.h (original)
>> +++ cfe/trunk/include/clang/AST/OpenMPClause.h Mon Jun 16 02:08:35 2014
>> @@ -431,7 +431,8 @@ public:
>> StmtRange children() { return StmtRange(); }
>> };
>> -/// \brief This represents 'proc_bind' clause in the '#pragma omp
>> ...' directive.
>> +/// \brief This represents 'proc_bind' clause in the '#pragma omp ...'
>> +/// directive.
>> ///
>> /// \code
>> /// #pragma omp parallel proc_bind(master)
>> @@ -471,8 +472,8 @@ public:
>> /// \param EndLoc Ending location of the clause.
>> ///
>> OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc,
>> - SourceLocation StartLoc, SourceLocation LParenLoc,
>> - SourceLocation EndLoc)
>> + SourceLocation StartLoc, SourceLocation LParenLoc,
>> + SourceLocation EndLoc)
>> : OMPClause(OMPC_proc_bind, StartLoc, EndLoc),
>> LParenLoc(LParenLoc),
>> Kind(A), KindKwLoc(ALoc) {}
>> @@ -739,6 +740,99 @@ public:
>> }
>> };
>> +/// \brief This represents clause 'reduction' in the '#pragma omp ...'
>> +/// directives.
>> +///
>> +/// \code
>> +/// #pragma omp parallel reduction(+:a,b)
>> +/// \endcode
>> +/// In this example directive '#pragma omp parallel' has clause
>> 'reduction'
>> +/// with operator '+' and the variables 'a' and 'b'.
>> +///
>> +class OMPReductionClause : public
>> OMPVarListClause<OMPReductionClause> {
>> + friend class OMPClauseReader;
>> + /// \brief Location of ':'.
>> + SourceLocation ColonLoc;
>> + /// \brief Nested name specifier for C++.
>> + NestedNameSpecifierLoc QualifierLoc;
>> + /// \brief Name of custom operator.
>> + DeclarationNameInfo NameInfo;
>> +
>> + /// \brief Build clause with number of variables \a N.
>> + ///
>> + /// \param StartLoc Starting location of the clause.
>> + /// \param LParenLoc Location of '('.
>> + /// \param EndLoc Ending location of the clause.
>> + /// \param ColonLoc Location of ':'.
>> + /// \param N Number of the variables in the clause.
>> + /// \param QualifierLoc The nested-name qualifier with location
>> information
>> + /// \param NameInfo The full name info for reduction identifier.
>> + ///
>> + OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
>> + SourceLocation ColonLoc, SourceLocation EndLoc,
>> unsigned N,
>> + NestedNameSpecifierLoc QualifierLoc,
>> + const DeclarationNameInfo &NameInfo)
>> + : OMPVarListClause<OMPReductionClause>(OMPC_reduction, StartLoc,
>> + LParenLoc, EndLoc, N),
>> + ColonLoc(ColonLoc), QualifierLoc(QualifierLoc),
>> NameInfo(NameInfo) {}
>> +
>> + /// \brief Build an empty clause.
>> + ///
>> + /// \param N Number of variables.
>> + ///
>> + explicit OMPReductionClause(unsigned N)
>> + : OMPVarListClause<OMPReductionClause>(OMPC_reduction,
>> SourceLocation(),
>> + SourceLocation(),
>> SourceLocation(),
>> + N),
>> + ColonLoc(), QualifierLoc(), NameInfo() {}
>> +
>> + /// \brief Sets location of ':' symbol in clause.
>> + void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
>> + /// \brief Sets the name info for specified reduction identifier.
>> + void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
>> + /// \brief Sets the nested name specifier.
>> + void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc =
>> NSL; }
>> +
>> +public:
>> + /// \brief Creates clause with a list of variables \a VL.
>> + ///
>> + /// \param StartLoc Starting location of the clause.
>> + /// \param LParenLoc Location of '('.
>> + /// \param ColonLoc Location of ':'.
>> + /// \param EndLoc Ending location of the clause.
>> + /// \param N Number of the variables in the clause.
>> + /// \param QualifierLoc The nested-name qualifier with location
>> information
>> + /// \param NameInfo The full name info for reduction identifier.
>> + ///
>> + static OMPReductionClause *
>> + Create(const ASTContext &C, SourceLocation StartLoc,
>> SourceLocation LParenLoc,
>> + SourceLocation ColonLoc, SourceLocation EndLoc,
>> ArrayRef<Expr *> VL,
>> + NestedNameSpecifierLoc QualifierLoc,
>> + const DeclarationNameInfo &NameInfo);
>> + /// \brief Creates an empty clause with the place for \a N variables.
>> + ///
>> + /// \param C AST context.
>> + /// \param N The number of variables.
>> + ///
>> + static OMPReductionClause *CreateEmpty(const ASTContext &C,
>> unsigned N);
>> +
>> + /// \brief Gets location of ':' symbol in clause.
>> + SourceLocation getColonLoc() const { return ColonLoc; }
>> + /// \brief Gets the name info for specified reduction identifier.
>> + const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
>> + /// \brief Gets the nested name specifier.
>> + NestedNameSpecifierLoc getQualifierLoc() const { return
>> QualifierLoc; }
>> +
>> + StmtRange children() {
>> + return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
>> + reinterpret_cast<Stmt **>(varlist_end()));
>> + }
>> +
>> + static bool classof(const OMPClause *T) {
>> + return T->getClauseKind() == OMPC_reduction;
>> + }
>> +};
>> +
>> /// \brief This represents clause 'linear' in the '#pragma omp ...'
>> /// directives.
>> ///
>>
>> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
>> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Mon Jun 16
>> 02:08:35 2014
>> @@ -2393,6 +2393,15 @@ bool RecursiveASTVisitor<Derived>::Visit
>> }
>> template <typename Derived>
>> +bool RecursiveASTVisitor<Derived>::VisitOMPReductionClause(
>> +
>> OMPReductionClause *C) {
>> + TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
>> + TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
>> + VisitOMPClauseList(C);
>> + return true;
>> +}
>> +
>> +template<typename Derived>
>> bool
>> RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
>> VisitOMPClauseList(C);
>> TraverseStmt(C->getStep());
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jun 16
>> 02:08:35 2014
>> @@ -6965,6 +6965,8 @@ def err_omp_firstprivate_incomplete_type
>> "a firstprivate variable with incomplete type %0">;
>> def err_omp_lastprivate_incomplete_type : Error<
>> "a lastprivate variable with incomplete type %0">;
>> +def err_omp_reduction_incomplete_type : Error<
>> + "a reduction variable with incomplete type %0">;
>> def err_omp_unexpected_clause_value : Error<
>> "expected %0 in OpenMP clause '%1'">;
>> def err_omp_expected_var_name : Error<
>> @@ -7044,6 +7046,24 @@ def err_omp_loop_cannot_use_stmt : Error
>> "'%0' statement cannot be used in OpenMP for loop">;
>> def err_omp_simd_region_cannot_use_stmt : Error<
>> "'%0' statement cannot be used in OpenMP simd region">;
>> +def err_omp_unknown_reduction_identifier : Error<
>> + "incorrect reduction identifier, expected one of '+', '-', '*',
>> '&', '|', '^', '&&', '||', 'min' or 'max'">;
>> +def err_omp_reduction_type_array : Error<
>> + "a reduction variable with array type %0">;
>> +def err_omp_reduction_ref_type_arg : Error<
>> + "argument of OpenMP clause 'reduction' must reference the same
>> object in all threads">;
>> +def err_omp_clause_not_arithmetic_type_arg : Error<
>> + "arguments of OpenMP clause 'reduction' for 'min' or 'max' must be
>> of %select{scalar|arithmetic}0 type">;
>> +def err_omp_clause_floating_type_arg : Error<
>> + "arguments of OpenMP clause 'reduction' with bitwise operators
>> cannot be of floating type">;
>> +def err_omp_once_referenced : Error<
>> + "variable can appear only once in OpenMP '%0' clause">;
>> +def note_omp_referenced : Note<
>> + "previously referenced here">;
>> +def err_omp_reduction_in_task : Error<
>> + "reduction variables may not be accessed in an explicit task">;
>> +def err_omp_reduction_id_not_compatible : Error<
>> + "variable of type %0 is not valid for specified reduction
>> operation">;
>> } // 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=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
>> +++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Mon Jun 16 02:08:35
>> 2014
>> @@ -47,6 +47,7 @@ OPENMP_CLAUSE(private, OMPPrivateClause)
>> OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
>> OPENMP_CLAUSE(lastprivate, OMPLastprivateClause)
>> OPENMP_CLAUSE(shared, OMPSharedClause)
>> +OPENMP_CLAUSE(reduction, OMPReductionClause)
>> OPENMP_CLAUSE(linear, OMPLinearClause)
>> OPENMP_CLAUSE(aligned, OMPAlignedClause)
>> OPENMP_CLAUSE(copyin, OMPCopyinClause)
>> @@ -60,6 +61,7 @@ OPENMP_PARALLEL_CLAUSE(proc_bind)
>> OPENMP_PARALLEL_CLAUSE(private)
>> OPENMP_PARALLEL_CLAUSE(firstprivate)
>> OPENMP_PARALLEL_CLAUSE(shared)
>> +OPENMP_PARALLEL_CLAUSE(reduction)
>> OPENMP_PARALLEL_CLAUSE(copyin)
>> // FIXME: more clauses allowed for directive 'omp simd'.
>>
>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>> +++ cfe/trunk/include/clang/Sema/Sema.h Mon Jun 16 02:08:35 2014
>> @@ -7355,13 +7355,13 @@ public:
>> SourceLocation LParenLoc,
>> SourceLocation EndLoc);
>> - OMPClause *ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
>> - ArrayRef<Expr *> Vars,
>> - Expr *TailExpr,
>> - SourceLocation StartLoc,
>> - SourceLocation LParenLoc,
>> - SourceLocation ColonLoc,
>> - SourceLocation EndLoc);
>> + OMPClause *
>> + ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *>
>> Vars,
>> + Expr *TailExpr, SourceLocation StartLoc,
>> + SourceLocation LParenLoc, SourceLocation
>> ColonLoc,
>> + SourceLocation EndLoc,
>> + CXXScopeSpec &ReductionIdScopeSpec,
>> + const DeclarationNameInfo &ReductionId);
>> /// \brief Called on well-formed 'private' clause.
>> OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
>> SourceLocation StartLoc,
>> @@ -7382,6 +7382,13 @@ public:
>> SourceLocation StartLoc,
>> SourceLocation LParenLoc,
>> SourceLocation EndLoc);
>> + /// \brief Called on well-formed 'reduction' clause.
>> + OMPClause *
>> + ActOnOpenMPReductionClause(ArrayRef<Expr *> VarList,
>> SourceLocation StartLoc,
>> + SourceLocation LParenLoc,
>> SourceLocation ColonLoc,
>> + SourceLocation EndLoc,
>> + CXXScopeSpec &ReductionIdScopeSpec,
>> + const DeclarationNameInfo &ReductionId);
>> /// \brief Called on well-formed 'linear' clause.
>> OMPClause *ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList,
>> Expr *Step,
>>
>> Modified: cfe/trunk/lib/AST/Stmt.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/AST/Stmt.cpp (original)
>> +++ cfe/trunk/lib/AST/Stmt.cpp Mon Jun 16 02:08:35 2014
>> @@ -1286,6 +1286,27 @@ void OMPExecutableDirective::setClauses(
>> std::copy(Clauses.begin(), Clauses.end(), getClauses().begin());
>> }
>> +OMPReductionClause *OMPReductionClause::Create(
>> + const ASTContext &C, SourceLocation StartLoc, SourceLocation
>> LParenLoc,
>> + SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *>
>> VL,
>> + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo
>> &NameInfo) {
>> + void *Mem =
>> C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
>> + llvm::alignOf<Expr
>> *>()) +
>> + sizeof(Expr *) * VL.size());
>> + OMPReductionClause *Clause = new (Mem) OMPReductionClause(
>> + StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(),
>> QualifierLoc, NameInfo);
>> + Clause->setVarRefs(VL);
>> + return Clause;
>> +}
>> +
>> +OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext
>> &C,
>> + unsigned N) {
>> + void *Mem =
>> C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
>> + llvm::alignOf<Expr
>> *>()) +
>> + sizeof(Expr *) * N);
>> + return new (Mem) OMPReductionClause(N);
>> +}
>> +
>> OMPParallelDirective *OMPParallelDirective::Create(
>> const ASTContext &C,
>> SourceLocation StartLoc,
>>
>> Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
>> +++ cfe/trunk/lib/AST/StmtPrinter.cpp Mon Jun 16 02:08:35 2014
>> @@ -676,6 +676,28 @@ void OMPClausePrinter::VisitOMPSharedCla
>> }
>> }
>> +void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause
>> *Node) {
>> + if (!Node->varlist_empty()) {
>> + OS << "reduction(";
>> + NestedNameSpecifier *QualifierLoc =
>> + Node->getQualifierLoc().getNestedNameSpecifier();
>> + OverloadedOperatorKind OOK =
>> + Node->getNameInfo().getName().getCXXOverloadedOperator();
>> + if (QualifierLoc == nullptr && OOK != OO_None) {
>> + // Print reduction identifier in C format
>> + OS << getOperatorSpelling(OOK);
>> + } else {
>> + // Use C++ format
>> + if (QualifierLoc != nullptr)
>> + QualifierLoc->print(OS, Policy);
>> + OS << Node->getNameInfo();
>> + }
>> + OS << ":";
>> + VisitOMPClauseList(Node, ' ');
>> + OS << ")";
>> + }
>> +}
>> +
>> void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
>> if (!Node->varlist_empty()) {
>> OS << "linear";
>>
>> Modified: cfe/trunk/lib/AST/StmtProfile.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/AST/StmtProfile.cpp (original)
>> +++ cfe/trunk/lib/AST/StmtProfile.cpp Mon Jun 16 02:08:35 2014
>> @@ -308,6 +308,13 @@ OMPClauseProfiler::VisitOMPLastprivateCl
>> void OMPClauseProfiler::VisitOMPSharedClause(const OMPSharedClause
>> *C) {
>> VisitOMPClauseList(C);
>> }
>> +void OMPClauseProfiler::VisitOMPReductionClause(
>> + const OMPReductionClause *C) {
>> + Profiler->VisitNestedNameSpecifier(
>> + C->getQualifierLoc().getNestedNameSpecifier());
>> + Profiler->VisitName(C->getNameInfo().getName());
>> + VisitOMPClauseList(C);
>> +}
>> void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause
>> *C) {
>> VisitOMPClauseList(C);
>> Profiler->VisitStmt(C->getStep());
>>
>> Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
>> +++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Mon Jun 16 02:08:35 2014
>> @@ -88,6 +88,7 @@ unsigned clang::getOpenMPSimpleClauseTyp
>> case OMPC_firstprivate:
>> case OMPC_lastprivate:
>> case OMPC_shared:
>> + case OMPC_reduction:
>> case OMPC_linear:
>> case OMPC_aligned:
>> case OMPC_copyin:
>> @@ -127,6 +128,7 @@ const char *clang::getOpenMPSimpleClause
>> case OMPC_firstprivate:
>> case OMPC_lastprivate:
>> case OMPC_shared:
>> + case OMPC_reduction:
>> case OMPC_linear:
>> case OMPC_aligned:
>> case OMPC_copyin:
>>
>> Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
>> +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Mon Jun 16 02:08:35 2014
>> @@ -258,7 +258,8 @@ bool Parser::ParseOpenMPSimpleVarList(Op
>> /// clause:
>> /// if-clause | num_threads-clause | safelen-clause |
>> default-clause |
>> /// private-clause | firstprivate-clause | shared-clause |
>> linear-clause |
>> -/// aligned-clause | collapse-clause | lastprivate-clause
>> +/// aligned-clause | collapse-clause | lastprivate-clause |
>> +/// reduction-clause
>> ///
>> OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
>> OpenMPClauseKind CKind, bool
>> FirstClause) {
>> @@ -307,6 +308,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope
>> case OMPC_firstprivate:
>> case OMPC_lastprivate:
>> case OMPC_shared:
>> + case OMPC_reduction:
>> case OMPC_linear:
>> case OMPC_aligned:
>> case OMPC_copyin:
>> @@ -394,6 +396,52 @@ OMPClause *Parser::ParseOpenMPSimpleClau
>> Tok.getLocation());
>> }
>> +static bool ParseReductionId(Parser &P, CXXScopeSpec
>> &ReductionIdScopeSpec,
>> + UnqualifiedId &ReductionId) {
>> + SourceLocation TemplateKWLoc;
>> + if (ReductionIdScopeSpec.isEmpty()) {
>> + auto OOK = OO_None;
>> + switch (P.getCurToken().getKind()) {
>> + case tok::plus:
>> + OOK = OO_Plus;
>> + break;
>> + case tok::minus:
>> + OOK = OO_Minus;
>> + break;
>> + case tok::star:
>> + OOK = OO_Star;
>> + break;
>> + case tok::amp:
>> + OOK = OO_Amp;
>> + break;
>> + case tok::pipe:
>> + OOK = OO_Pipe;
>> + break;
>> + case tok::caret:
>> + OOK = OO_Caret;
>> + break;
>> + case tok::ampamp:
>> + OOK = OO_AmpAmp;
>> + break;
>> + case tok::pipepipe:
>> + OOK = OO_PipePipe;
>> + break;
>> + default:
>> + break;
>> + }
>> + if (OOK != OO_None) {
>> + SourceLocation OpLoc = P.ConsumeToken();
>> + SourceLocation SymbolLocations[] = { OpLoc, OpLoc,
>> SourceLocation() };
>> + ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
>> + return false;
>> + }
>> + }
>> + return P.ParseUnqualifiedId(ReductionIdScopeSpec,
>> /*EnteringContext*/ false,
>> + /*AllowDestructorName*/ false,
>> + /*AllowConstructorName*/ false,
>> ParsedType(),
>> + TemplateKWLoc, ReductionId);
>> +}
>> +
>> /// \brief Parsing of OpenMP clause 'private', 'firstprivate',
>> 'lastprivate',
>> /// 'shared', 'copyin', or 'reduction'.
>> ///
>> @@ -409,19 +457,44 @@ OMPClause *Parser::ParseOpenMPSimpleClau
>> /// 'linear' '(' list [ ':' linear-step ] ')'
>> /// aligned-clause:
>> /// 'aligned' '(' list [ ':' alignment ] ')'
>> +/// reduction-clause:
>> +/// 'reduction' '(' reduction-identifier ':' list ')'
>> ///
>> OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
>> SourceLocation Loc = Tok.getLocation();
>> SourceLocation LOpen = ConsumeToken();
>> SourceLocation ColonLoc = SourceLocation();
>> + // Optional scope specifier and unqualified id for reduction
>> identifier.
>> + CXXScopeSpec ReductionIdScopeSpec;
>> + UnqualifiedId ReductionId;
>> + bool InvalidReductionId = false;
>> // Parse '('.
>> BalancedDelimiterTracker T(*this, tok::l_paren,
>> tok::annot_pragma_openmp_end);
>> if (T.expectAndConsume(diag::err_expected_lparen_after,
>> getOpenMPClauseName(Kind)))
>> return nullptr;
>> + // Handle reduction-identifier for reduction clause.
>> + if (Kind == OMPC_reduction) {
>> + ColonProtectionRAIIObject ColonRAII(*this);
>> + if (getLangOpts().CPlusPlus) {
>> + ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec,
>> ParsedType(), false);
>> + }
>> + InvalidReductionId =
>> + ParseReductionId(*this, ReductionIdScopeSpec, ReductionId);
>> + if (InvalidReductionId) {
>> + SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
>> + StopBeforeMatch);
>> + }
>> + if (Tok.is(tok::colon)) {
>> + ColonLoc = ConsumeToken();
>> + } else {
>> + Diag(Tok, diag::warn_pragma_expected_colon) << "reduction
>> identifier";
>> + }
>> + }
>> +
>> SmallVector<Expr *, 5> Vars;
>> - bool IsComma = true;
>> + bool IsComma = !InvalidReductionId;
>> const bool MayHaveTail = (Kind == OMPC_linear || Kind ==
>> OMPC_aligned);
>> while (IsComma || (Tok.isNot(tok::r_paren) &&
>> Tok.isNot(tok::colon) &&
>> Tok.isNot(tok::annot_pragma_openmp_end))) {
>> @@ -460,10 +533,13 @@ OMPClause *Parser::ParseOpenMPVarListCla
>> // Parse ')'.
>> T.consumeClose();
>> - if (Vars.empty() || (MustHaveTail && !TailExpr))
>> + if (Vars.empty() || (MustHaveTail && !TailExpr) ||
>> InvalidReductionId)
>> return nullptr;
>> - return Actions.ActOnOpenMPVarListClause(Kind, Vars, TailExpr, Loc,
>> LOpen,
>> - ColonLoc, Tok.getLocation());
>> + return Actions.ActOnOpenMPVarListClause(
>> + Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
>> + ReductionIdScopeSpec,
>> + ReductionId.isValid() ?
>> Actions.GetNameFromUnqualifiedId(ReductionId)
>> + : DeclarationNameInfo());
>> }
>>
>> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Jun 16 02:08:35 2014
>> @@ -119,6 +119,10 @@ public:
>> /// attribute in \a DKind directive.
>> DSAVarData hasDSA(VarDecl *D, OpenMPClauseKind CKind,
>> OpenMPDirectiveKind DKind = OMPD_unknown);
>> + /// \brief Checks if the specified variables has \a CKind
>> data-sharing
>> + /// attribute in an innermost \a DKind directive.
>> + DSAVarData hasInnermostDSA(VarDecl *D, OpenMPClauseKind CKind,
>> + OpenMPDirectiveKind DKind);
>> /// \brief Returns currently analyzed directive.
>> OpenMPDirectiveKind getCurrentDirective() const {
>> @@ -154,7 +158,6 @@ 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.
>> - // TODO
>> if (!D->isFunctionOrMethodVarDecl())
>> DVar.CKind = OMPC_shared;
>> @@ -214,7 +217,6 @@ DSAStackTy::DSAVarData DSAStackTy::getDS
>> // In a task construct, if no default clause is present, a
>> variable that in
>> // the enclosing context is determined to be shared by all
>> implicit tasks
>> // bound to the current team is shared.
>> - // TODO
>> if (DVar.DKind == OMPD_task) {
>> DSAVarData DVarTemp;
>> for (StackTy::reverse_iterator I = std::next(Iter),
>> @@ -399,6 +401,21 @@ DSAStackTy::DSAVarData DSAStackTy::hasDS
>> return DSAVarData();
>> }
>> +DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(VarDecl *D,
>> + OpenMPClauseKind
>> CKind,
>> +
>> OpenMPDirectiveKind DKind) {
>> + assert(DKind != OMPD_unknown && "Directive must be specified
>> explicitly");
>> + for (auto I = Stack.rbegin(), EE = std::prev(Stack.rend()); I !=
>> EE; ++I) {
>> + if (DKind != I->Directive)
>> + continue;
>> + DSAVarData DVar = getDSA(I, D);
>> + if (DVar.CKind == CKind)
>> + return DVar;
>> + return DSAVarData();
>> + }
>> + return DSAVarData();
>> +}
>> +
>> void Sema::InitDataSharingAttributesStack() {
>> VarDataSharingAttributesStack = new DSAStackTy(*this);
>> }
>> @@ -702,7 +719,16 @@ public:
>> // 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.
>> - // TODO:
>> + DVar = Stack->hasInnermostDSA(VD, OMPC_reduction, OMPD_parallel);
>> + if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) {
>> + ErrorFound = true;
>> + Actions.Diag(ELoc, diag::err_omp_reduction_in_task);
>> + if (DVar.RefExpr) {
>> + Actions.Diag(DVar.RefExpr->getExprLoc(),
>> diag::note_omp_explicit_dsa)
>> + << getOpenMPClauseName(OMPC_reduction);
>> + }
>> + return;
>> + }
>> // Define implicit data-sharing attributes for task.
>> DVar = Stack->getImplicitDSA(VD);
>> @@ -1357,6 +1383,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl
>> case OMPC_firstprivate:
>> case OMPC_lastprivate:
>> case OMPC_shared:
>> + case OMPC_reduction:
>> case OMPC_linear:
>> case OMPC_aligned:
>> case OMPC_copyin:
>> @@ -1532,6 +1559,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause
>> case OMPC_firstprivate:
>> case OMPC_lastprivate:
>> case OMPC_shared:
>> + case OMPC_reduction:
>> case OMPC_linear:
>> case OMPC_aligned:
>> case OMPC_copyin:
>> @@ -1617,11 +1645,11 @@ OMPClause *Sema::ActOnOpenMPProcBindClau
>> OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
>> }
>> -OMPClause *
>> -Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr
>> *> VarList,
>> - Expr *TailExpr, SourceLocation StartLoc,
>> - SourceLocation LParenLoc,
>> - SourceLocation ColonLoc,
>> SourceLocation EndLoc) {
>> +OMPClause *Sema::ActOnOpenMPVarListClause(
>> + OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
>> + SourceLocation StartLoc, SourceLocation LParenLoc,
>> SourceLocation ColonLoc,
>> + SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
>> + const DeclarationNameInfo &ReductionId) {
>> OMPClause *Res = nullptr;
>> switch (Kind) {
>> case OMPC_private:
>> @@ -1636,6 +1664,11 @@ Sema::ActOnOpenMPVarListClause(OpenMPCla
>> case OMPC_shared:
>> Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc,
>> EndLoc);
>> break;
>> + case OMPC_reduction:
>> + Res =
>> + ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc,
>> ColonLoc,
>> + EndLoc, ReductionIdScopeSpec,
>> ReductionId);
>> + break;
>> case OMPC_linear:
>> Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc,
>> LParenLoc,
>> ColonLoc, EndLoc);
>> @@ -2194,6 +2227,323 @@ OMPClause *Sema::ActOnOpenMPSharedClause
>> return OMPSharedClause::Create(Context, StartLoc, LParenLoc,
>> EndLoc, Vars);
>> }
>> +namespace {
>> +class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
>> + DSAStackTy *Stack;
>> +
>> +public:
>> + bool VisitDeclRefExpr(DeclRefExpr *E) {
>> + if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
>> + DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD);
>> + if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
>> + return false;
>> + if (DVar.CKind != OMPC_unknown)
>> + return true;
>> + DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(VD,
>> OMPC_private);
>> + DSAStackTy::DSAVarData DVarFirstprivate =
>> + Stack->hasDSA(VD, OMPC_firstprivate);
>> + DSAStackTy::DSAVarData DVarReduction = Stack->hasDSA(VD,
>> OMPC_reduction);
>> + if (DVarPrivate.CKind != OMPC_unknown ||
>> + DVarFirstprivate.CKind != OMPC_unknown ||
>> + DVarReduction.CKind != OMPC_unknown)
>> + return true;
>> + return false;
>> + }
>> + return false;
>> + }
>> + bool VisitStmt(Stmt *S) {
>> + for (auto Child : S->children()) {
>> + if (Child && Visit(Child))
>> + return true;
>> + }
>> + return false;
>> + }
>> + DSARefChecker(DSAStackTy *S) : Stack(S) {}
>> +};
>> +}
>> +
>> +OMPClause *Sema::ActOnOpenMPReductionClause(
>> + ArrayRef<Expr *> VarList, SourceLocation StartLoc,
>> SourceLocation LParenLoc,
>> + SourceLocation ColonLoc, SourceLocation EndLoc,
>> + CXXScopeSpec &ReductionIdScopeSpec,
>> + const DeclarationNameInfo &ReductionId) {
>> + // TODO: Allow scope specification search when 'declare reduction' is
>> + // supported.
>> + assert(ReductionIdScopeSpec.isEmpty() &&
>> + "No support for scoped reduction identifiers yet.");
>> +
>> + auto DN = ReductionId.getName();
>> + auto OOK = DN.getCXXOverloadedOperator();
>> + BinaryOperatorKind BOK = BO_Comma;
>> +
>> + // OpenMP [2.14.3.6, reduction clause]
>> + // C
>> + // reduction-identifier is either an identifier or one of the
>> following
>> + // operators: +, -, *, &, |, ^, && and ||
>> + // C++
>> + // reduction-identifier is either an id-expression or one of the
>> following
>> + // operators: +, -, *, &, |, ^, && and ||
>> + // FIXME: Only 'min' and 'max' identifiers are supported for now.
>> + switch (OOK) {
>> + case OO_Plus:
>> + case OO_Minus:
>> + BOK = BO_AddAssign;
>> + break;
>> + case OO_Star:
>> + BOK = BO_MulAssign;
>> + break;
>> + case OO_Amp:
>> + BOK = BO_AndAssign;
>> + break;
>> + case OO_Pipe:
>> + BOK = BO_OrAssign;
>> + break;
>> + case OO_Caret:
>> + BOK = BO_XorAssign;
>> + break;
>> + case OO_AmpAmp:
>> + BOK = BO_LAnd;
>> + break;
>> + case OO_PipePipe:
>> + BOK = BO_LOr;
>> + break;
>> + default:
>> + if (auto II = DN.getAsIdentifierInfo()) {
>> + if (II->isStr("max"))
>> + BOK = BO_GT;
>> + else if (II->isStr("min"))
>> + BOK = BO_LT;
>> + }
>> + break;
>> + }
>> + SourceRange ReductionIdRange;
>> + if (ReductionIdScopeSpec.isValid()) {
>> + ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
>> + }
>> + ReductionIdRange.setEnd(ReductionId.getEndLoc());
>> + if (BOK == BO_Comma) {
>> + // Not allowed reduction identifier is found.
>> + Diag(ReductionId.getLocStart(),
>> diag::err_omp_unknown_reduction_identifier)
>> + << ReductionIdRange;
>> + return nullptr;
>> + }
>> +
>> + SmallVector<Expr *, 8> Vars;
>> + for (auto RefExpr : VarList) {
>> + assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
>> + if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
>> + // It will be analyzed later.
>> + Vars.push_back(RefExpr);
>> + continue;
>> + }
>> +
>> + if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
>> + RefExpr->isInstantiationDependent() ||
>> + RefExpr->containsUnexpandedParameterPack()) {
>> + // It will be analyzed later.
>> + Vars.push_back(RefExpr);
>> + continue;
>> + }
>> +
>> + auto ELoc = RefExpr->getExprLoc();
>> + auto ERange = RefExpr->getSourceRange();
>> + // OpenMP [2.1, C/C++]
>> + // A list item is a variable or array section, subject to the
>> restrictions
>> + // specified in Section 2.4 on page 42 and in each of the sections
>> + // describing clauses and directives for which a list appears.
>> + // OpenMP [2.14.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.
>> + auto DE = dyn_cast<DeclRefExpr>(RefExpr);
>> + if (!DE || !isa<VarDecl>(DE->getDecl())) {
>> + Diag(ELoc, diag::err_omp_expected_var_name) << ERange;
>> + continue;
>> + }
>> + auto D = DE->getDecl();
>> + auto VD = cast<VarDecl>(D);
>> + auto Type = VD->getType();
>> + // 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_reduction_incomplete_type))
>> + continue;
>> + // OpenMP [2.14.3.6, reduction clause, Restrictions]
>> + // Arrays may not appear in a reduction clause.
>> + if (Type.getNonReferenceType()->isArrayType()) {
>> + Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange;
>> + bool IsDecl =
>> + VD->isThisDeclarationADefinition(Context) ==
>> VarDecl::DeclarationOnly;
>> + Diag(VD->getLocation(),
>> + IsDecl ? diag::note_previous_decl : diag::note_defined_here)
>> + << VD;
>> + continue;
>> + }
>> + // OpenMP [2.14.3.6, reduction clause, Restrictions]
>> + // A list item that appears in a reduction clause must not be
>> + // const-qualified.
>> + if (Type.getNonReferenceType().isConstant(Context)) {
>> + Diag(ELoc, diag::err_omp_const_variable)
>> + << getOpenMPClauseName(OMPC_reduction) << Type << ERange;
>> + bool IsDecl =
>> + VD->isThisDeclarationADefinition(Context) ==
>> VarDecl::DeclarationOnly;
>> + Diag(VD->getLocation(),
>> + IsDecl ? diag::note_previous_decl : diag::note_defined_here)
>> + << VD;
>> + continue;
>> + }
>> + // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
>> + // If a list-item is a reference type then it must bind to the
>> same object
>> + // for all threads of the team.
>> + VarDecl *VDDef = VD->getDefinition();
>> + if (Type->isReferenceType() && VDDef) {
>> + DSARefChecker Check(DSAStack);
>> + if (Check.Visit(VDDef->getInit())) {
>> + Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
>> + Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
>> + continue;
>> + }
>> + }
>> + // OpenMP [2.14.3.6, reduction clause, Restrictions]
>> + // The type of a list item that appears in a reduction clause
>> must be valid
>> + // for the reduction-identifier. For a max or min reduction in
>> C, the type
>> + // of the list item must be an allowed arithmetic data type:
>> char, int,
>> + // float, double, or _Bool, possibly modified with long, short,
>> signed, or
>> + // unsigned. For a max or min reduction in C++, the type of the
>> list item
>> + // must be an allowed arithmetic data type: char, wchar_t, int,
>> float,
>> + // double, or bool, possibly modified with long, short, signed,
>> or unsigned.
>> + if ((BOK == BO_GT || BOK == BO_LT) &&
>> + !(Type->isScalarType() ||
>> + (getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
>> + Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
>> + << getLangOpts().CPlusPlus;
>> + bool IsDecl =
>> + VD->isThisDeclarationADefinition(Context) ==
>> VarDecl::DeclarationOnly;
>> + Diag(VD->getLocation(),
>> + IsDecl ? diag::note_previous_decl : diag::note_defined_here)
>> + << VD;
>> + continue;
>> + }
>> + if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK ==
>> BO_XorAssign) &&
>> + !getLangOpts().CPlusPlus && Type->isFloatingType()) {
>> + Diag(ELoc, diag::err_omp_clause_floating_type_arg);
>> + bool IsDecl =
>> + VD->isThisDeclarationADefinition(Context) ==
>> VarDecl::DeclarationOnly;
>> + Diag(VD->getLocation(),
>> + IsDecl ? diag::note_previous_decl : diag::note_defined_here)
>> + << VD;
>> + continue;
>> + }
>> + bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
>> + getDiagnostics().setSuppressAllDiagnostics(true);
>> + ExprResult ReductionOp =
>> + BuildBinOp(DSAStack->getCurScope(),
>> ReductionId.getLocStart(), BOK,
>> + RefExpr, RefExpr);
>> + getDiagnostics().setSuppressAllDiagnostics(Suppress);
>> + if (ReductionOp.isInvalid()) {
>> + Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
>> + << ReductionIdRange;
>> + bool IsDecl =
>> + VD->isThisDeclarationADefinition(Context) ==
>> VarDecl::DeclarationOnly;
>> + Diag(VD->getLocation(),
>> + IsDecl ? diag::note_previous_decl : diag::note_defined_here)
>> + << VD;
>> + continue;
>> + }
>> +
>> + // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
>> Referenced
>> + // in a Construct]
>> + // Variables with the predetermined data-sharing attributes may
>> not be
>> + // listed in data-sharing attributes clauses, except for the cases
>> + // 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.
>> + // OpenMP [2.14.3.6, Restrictions, p.3]
>> + // Any number of reduction clauses can be specified on the
>> directive,
>> + // but a list item can appear only once in the reduction
>> clauses for that
>> + // directive.
>> + DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
>> + if (DVar.CKind == OMPC_reduction) {
>> + Diag(ELoc, diag::err_omp_once_referenced)
>> + << getOpenMPClauseName(OMPC_reduction);
>> + if (DVar.RefExpr) {
>> + Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
>> + }
>> + } else if (DVar.CKind != OMPC_unknown) {
>> + Diag(ELoc, diag::err_omp_wrong_dsa)
>> + << getOpenMPClauseName(DVar.CKind)
>> + << getOpenMPClauseName(OMPC_reduction);
>> + if (DVar.RefExpr) {
>> + Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
>> + << getOpenMPClauseName(DVar.CKind);
>> + } else {
>> + Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
>> + << getOpenMPClauseName(DVar.CKind);
>> + }
>> + continue;
>> + }
>> +
>> + // OpenMP [2.14.3.6, Restrictions, p.1]
>> + // A list item that appears in a reduction clause of a worksharing
>> + // construct must be shared in the parallel regions to which
>> any of the
>> + // worksharing regions arising from the worksharing construct
>> bind.
>> + // TODO Implement it later.
>> +
>> + CXXRecordDecl *RD = getLangOpts().CPlusPlus
>> + ?
>> Type.getNonReferenceType()->getAsCXXRecordDecl()
>> + : nullptr;
>> + if (RD) {
>> + CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
>> + PartialDiagnostic PD =
>> + PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
>> + if (!CD || CheckConstructorAccess(
>> + ELoc, CD,
>> InitializedEntity::InitializeTemporary(Type),
>> + CD->getAccess(), PD) == AR_inaccessible ||
>> + CD->isDeleted()) {
>> + Diag(ELoc, diag::err_omp_required_method)
>> + << getOpenMPClauseName(OMPC_reduction) << 0;
>> + bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
>> + VarDecl::DeclarationOnly;
>> + Diag(VD->getLocation(),
>> + IsDecl ? diag::note_previous_decl :
>> diag::note_defined_here)
>> + << VD;
>> + Diag(RD->getLocation(), diag::note_previous_decl) << RD;
>> + continue;
>> + }
>> + MarkFunctionReferenced(ELoc, CD);
>> + DiagnoseUseOfDecl(CD, ELoc);
>> +
>> + CXXDestructorDecl *DD = RD->getDestructor();
>> + if (DD) {
>> + if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
>> + DD->isDeleted()) {
>> + Diag(ELoc, diag::err_omp_required_method)
>> + << getOpenMPClauseName(OMPC_reduction) << 4;
>> + bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
>> + VarDecl::DeclarationOnly;
>> + Diag(VD->getLocation(),
>> + IsDecl ? diag::note_previous_decl :
>> diag::note_defined_here)
>> + << VD;
>> + Diag(RD->getLocation(), diag::note_previous_decl) << RD;
>> + continue;
>> + }
>> + MarkFunctionReferenced(ELoc, DD);
>> + DiagnoseUseOfDecl(DD, ELoc);
>> + }
>> + }
>> +
>> + DSAStack->addDSA(VD, DE, OMPC_reduction);
>> + Vars.push_back(DE);
>> + }
>> +
>> + if (Vars.empty())
>> + return nullptr;
>> +
>> + return OMPReductionClause::Create(
>> + Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
>> + ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId);
>> +}
>> +
>> OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList,
>> Expr *Step,
>> SourceLocation StartLoc,
>> SourceLocation LParenLoc,
>>
>> Modified: cfe/trunk/lib/Sema/TreeTransform.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
>> +++ cfe/trunk/lib/Sema/TreeTransform.h Mon Jun 16 02:08:35 2014
>> @@ -1425,6 +1425,22 @@ public:
>> EndLoc);
>> }
>> + /// \brief Build a new OpenMP 'reduction' clause.
>> + ///
>> + /// By default, performs semantic analysis to build the new
>> statement.
>> + /// Subclasses may override this routine to provide different
>> behavior.
>> + OMPClause *RebuildOMPReductionClause(ArrayRef<Expr *> VarList,
>> + SourceLocation StartLoc,
>> + SourceLocation LParenLoc,
>> + SourceLocation ColonLoc,
>> + SourceLocation EndLoc,
>> + CXXScopeSpec
>> &ReductionIdScopeSpec,
>> + const DeclarationNameInfo
>> &ReductionId) {
>> + return getSema().ActOnOpenMPReductionClause(
>> + VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
>> ReductionIdScopeSpec,
>> + ReductionId);
>> + }
>> +
>> /// \brief Build a new OpenMP 'linear' clause.
>> ///
>> /// By default, performs semantic analysis to build the new
>> OpenMP clause.
>> @@ -6348,10 +6364,8 @@ StmtResult TreeTransform<Derived>::Trans
>> I != E; ++I) {
>> if (*I) {
>> OMPClause *Clause = getDerived().TransformOMPClause(*I);
>> - if (!Clause) {
>> - return StmtError();
>> - }
>> - TClauses.push_back(Clause);
>> + if (Clause)
>> + TClauses.push_back(Clause);
>> } else {
>> TClauses.push_back(nullptr);
>> }
>> @@ -6361,7 +6375,7 @@ StmtResult TreeTransform<Derived>::Trans
>> }
>> StmtResult AssociatedStmt =
>> getDerived().TransformStmt(D->getAssociatedStmt());
>> - if (AssociatedStmt.isInvalid()) {
>> + if (AssociatedStmt.isInvalid() || TClauses.size() !=
>> Clauses.size()) {
>> return StmtError();
>> }
>> @@ -6510,6 +6524,31 @@ TreeTransform<Derived>::TransformOMPShar
>> template <typename Derived>
>> OMPClause *
>> +TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause
>> *C) {
>> + llvm::SmallVector<Expr *, 16> Vars;
>> + Vars.reserve(C->varlist_size());
>> + for (auto *VE : C->varlists()) {
>> + ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
>> + if (EVar.isInvalid())
>> + return nullptr;
>> + Vars.push_back(EVar.get());
>> + }
>> + CXXScopeSpec ReductionIdScopeSpec;
>> + ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
>> +
>> + DeclarationNameInfo NameInfo = C->getNameInfo();
>> + if (NameInfo.getName()) {
>> + NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
>> + if (!NameInfo.getName())
>> + return nullptr;
>> + }
>> + return getDerived().RebuildOMPReductionClause(
>> + Vars, C->getLocStart(), C->getLParenLoc(), C->getColonLoc(),
>> + C->getLocEnd(), ReductionIdScopeSpec, NameInfo);
>> +}
>> +
>> +template <typename Derived>
>> +OMPClause *
>> TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
>> llvm::SmallVector<Expr *, 16> Vars;
>> Vars.reserve(C->varlist_size());
>> @@ -10017,7 +10056,11 @@ TreeTransform<Derived>::TransformCapture
>> }
>> getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
>> S->getCapturedRegionKind(),
>> Params);
>> - StmtResult Body = getDerived().TransformStmt(S->getCapturedStmt());
>> + StmtResult Body;
>> + {
>> + Sema::CompoundScopeRAII CompoundScope(getSema());
>> + Body = getDerived().TransformStmt(S->getCapturedStmt());
>> + }
>> if (Body.isInvalid()) {
>> getSema().ActOnCapturedRegionError();
>>
>> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Mon Jun 16 02:08:35
>> 2014
>> @@ -1703,6 +1703,9 @@ OMPClause *OMPClauseReader::readClause()
>> case OMPC_shared:
>> C = OMPSharedClause::CreateEmpty(Context, Record[Idx++]);
>> break;
>> + case OMPC_reduction:
>> + C = OMPReductionClause::CreateEmpty(Context, Record[Idx++]);
>> + break;
>> case OMPC_linear:
>> C = OMPLinearClause::CreateEmpty(Context, Record[Idx++]);
>> break;
>> @@ -1789,6 +1792,24 @@ void OMPClauseReader::VisitOMPSharedClau
>> unsigned NumVars = C->varlist_size();
>> SmallVector<Expr *, 16> Vars;
>> Vars.reserve(NumVars);
>> + for (unsigned i = 0; i != NumVars; ++i)
>> + Vars.push_back(Reader->Reader.ReadSubExpr());
>> + C->setVarRefs(Vars);
>> +}
>> +
>> +void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) {
>> + C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
>> + C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
>> + NestedNameSpecifierLoc NNSL =
>> + Reader->Reader.ReadNestedNameSpecifierLoc(Reader->F, Record, Idx);
>> + DeclarationNameInfo DNI;
>> + Reader->ReadDeclarationNameInfo(DNI, Record, Idx);
>> + C->setQualifierLoc(NNSL);
>> + C->setNameInfo(DNI);
>> +
>> + unsigned NumVars = C->varlist_size();
>> + SmallVector<Expr *, 16> Vars;
>> + Vars.reserve(NumVars);
>> for (unsigned i = 0; i != NumVars; ++i)
>> Vars.push_back(Reader->Reader.ReadSubExpr());
>> C->setVarRefs(Vars);
>>
>> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Mon Jun 16 02:08:35
>> 2014
>> @@ -1735,6 +1735,16 @@ void OMPClauseWriter::VisitOMPSharedClau
>> Writer->Writer.AddStmt(VE);
>> }
>> +void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) {
>> + Record.push_back(C->varlist_size());
>> + Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
>> + Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
>> + Writer->Writer.AddNestedNameSpecifierLoc(C->getQualifierLoc(),
>> Record);
>> + Writer->Writer.AddDeclarationNameInfo(C->getNameInfo(), Record);
>> + for (auto *VE : C->varlists())
>> + Writer->Writer.AddStmt(VE);
>> +}
>> +
>> void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
>> Record.push_back(C->varlist_size());
>> Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
>>
>> 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=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/test/OpenMP/parallel_ast_print.cpp (original)
>> +++ cfe/trunk/test/OpenMP/parallel_ast_print.cpp Mon Jun 16 02:08:35
>> 2014
>> @@ -35,9 +35,9 @@ T tmain(T argc, T *argv) {
>> S<T> s;
>> #pragma omp parallel
>> a=2;
>> -#pragma omp parallel default(none), private(argc,b)
>> firstprivate(argv) shared (d) if (argc > 0) num_threads(C)
>> copyin(S<T>::TS) proc_bind(master)
>> +#pragma omp parallel default(none), private(argc,b)
>> firstprivate(argv) shared (d) if (argc > 0) num_threads(C)
>> copyin(S<T>::TS) proc_bind(master) reduction(+:c) reduction(max:e)
>> foo();
>> -#pragma omp parallel if (C) num_threads(s) proc_bind(close)
>> +#pragma omp parallel if (C) num_threads(s) proc_bind(close)
>> reduction(^:e, f) reduction(&& : g)
>> foo();
>> return 0;
>> }
>> @@ -48,9 +48,9 @@ T tmain(T argc, T *argv) {
>> // CHECK-NEXT: S<int> s;
>> // CHECK-NEXT: #pragma omp parallel
>> // CHECK-NEXT: a = 2;
>> -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b)
>> firstprivate(argv) shared(d) if(argc > 0) num_threads(5)
>> copyin(S<int>::TS) proc_bind(master)
>> +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b)
>> firstprivate(argv) shared(d) if(argc > 0) num_threads(5)
>> copyin(S<int>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
>> // CHECK-NEXT: foo()
>> -// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s)
>> proc_bind(close)
>> +// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s)
>> proc_bind(close) reduction(^: e,f) reduction(&&: g)
>> // CHECK-NEXT: foo()
>> // CHECK: template <typename T = long, int C = 1> long tmain(long
>> argc, long *argv) {
>> // CHECK-NEXT: long b = argc, c, d, e, f, g;
>> @@ -58,9 +58,9 @@ T tmain(T argc, T *argv) {
>> // CHECK-NEXT: S<long> s;
>> // CHECK-NEXT: #pragma omp parallel
>> // CHECK-NEXT: a = 2;
>> -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b)
>> firstprivate(argv) shared(d) if(argc > 0) num_threads(1)
>> copyin(S<long>::TS) proc_bind(master)
>> +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b)
>> firstprivate(argv) shared(d) if(argc > 0) num_threads(1)
>> copyin(S<long>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
>> // CHECK-NEXT: foo()
>> -// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s)
>> proc_bind(close)
>> +// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s)
>> proc_bind(close) reduction(^: e,f) reduction(&&: g)
>> // CHECK-NEXT: foo()
>> // CHECK: template <typename T, int C> T tmain(T argc, T *argv) {
>> // CHECK-NEXT: T b = argc, c, d, e, f, g;
>> @@ -68,9 +68,9 @@ T tmain(T argc, T *argv) {
>> // CHECK-NEXT: S<T> s;
>> // CHECK-NEXT: #pragma omp parallel
>> // CHECK-NEXT: a = 2;
>> -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b)
>> firstprivate(argv) shared(d) if(argc > 0) num_threads(C)
>> copyin(S<T>::TS) proc_bind(master)
>> +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b)
>> firstprivate(argv) shared(d) if(argc > 0) num_threads(C)
>> copyin(S<T>::TS) proc_bind(master) reduction(+: c) reduction(max: e)
>> // CHECK-NEXT: foo()
>> -// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s)
>> proc_bind(close)
>> +// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s)
>> proc_bind(close) reduction(^: e,f) reduction(&&: g)
>> // CHECK-NEXT: foo()
>> enum Enum { };
>> @@ -86,8 +86,8 @@ int main (int argc, char **argv) {
>> // CHECK-NEXT: #pragma omp parallel
>> a=2;
>> // CHECK-NEXT: a = 2;
>> -#pragma omp parallel default(none), private(argc,b)
>> firstprivate(argv) if (argc > 0) num_threads(ee) copyin(a)
>> proc_bind(spread)
>> -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b)
>> firstprivate(argv) if(argc > 0) num_threads(ee) copyin(a)
>> proc_bind(spread)
>> +#pragma omp parallel default(none), private(argc,b)
>> firstprivate(argv) if (argc > 0) num_threads(ee) copyin(a)
>> proc_bind(spread) reduction(| : c, d) reduction(* : e)
>> +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b)
>> firstprivate(argv) if(argc > 0) num_threads(ee) copyin(a)
>> proc_bind(spread) reduction(|: c,d) reduction(*: e)
>> foo();
>> // CHECK-NEXT: foo();
>> return tmain<int, 5>(b, &b) + tmain<long, 1>(x, &x);
>>
>> Added: cfe/trunk/test/OpenMP/parallel_reduction_messages.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_reduction_messages.cpp?rev=211007&view=auto
>>
>> ==============================================================================
>>
>> --- cfe/trunk/test/OpenMP/parallel_reduction_messages.cpp (added)
>> +++ cfe/trunk/test/OpenMP/parallel_reduction_messages.cpp Mon Jun 16
>> 02:08:35 2014
>> @@ -0,0 +1,215 @@
>> +// RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 -o - %s
>> +
>> +void foo() {
>> +}
>> +
>> +bool foobool(int argc) {
>> + return argc;
>> +}
>> +
>> +struct S1; // expected-note {{declared here}} expected-note 4
>> {{forward declaration of 'S1'}}
>> +extern S1 a;
>> +class S2 {
>> + mutable int a;
>> + S2 &operator +=(const S2 &arg) {return (*this);}
>> +public:
>> + S2():a(0) { }
>> + S2(S2 &s2):a(s2.a) { }
>> + static float S2s; // expected-note 2 {{predetermined as shared}}
>> + static const float S2sc;
>> +};
>> +const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
>> +S2 b; // expected-note 2 {{'b' defined here}}
>> +const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
>> +class S3 {
>> + int a;
>> +public:
>> + S3():a(0) { }
>> + S3(const S3 &s3):a(s3.a) { }
>> + S3 operator +=(const S3 &arg1) {return arg1;}
>> +};
>> +int operator +=(const S3 &arg1, const S3 &arg2) {return 5;}
>> +S3 c; // expected-note 2 {{'c' defined here}}
>> +const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
>> +extern const int f; // expected-note 4 {{'f' declared here}}
>> +class S4 { // expected-note {{'S4' declared here}}
>> + int a;
>> + S4();
>> + S4(const S4 &s4);
>> + S4 &operator +=(const S4 &arg) {return (*this);}
>> +public:
>> + S4(int v):a(v) { }
>> +};
>> +S4 &operator &=(S4 &arg1, S4 &arg2) {return arg1;}
>> +class S5 {
>> + int a;
>> + S5():a(0) {}
>> + S5(const S5 &s5):a(s5.a) { }
>> + S5 &operator +=(const S5 &arg);
>> +public:
>> + S5(int v):a(v) { }
>> +};
>> +class S6 {
>> + int a;
>> + public:
>> + S6():a(6){ }
>> + operator int() { return 6; }
>> +} o; // expected-note 2 {{'o' defined here}}
>> +
>> +S3 h, k;
>> +#pragma omp threadprivate(h) // expected-note 2 {{defined as
>> threadprivate or thread local}}
>> +
>> +template <class T> // expected-note {{declared here}}
>> +T tmain(T argc) { // expected-note 2 {{'argc' defined here}}
>> + const T d = T(); // expected-note 4 {{'d' defined here}}
>> + const T da[5] = { T() }; // expected-note 2 {{'da' defined here}}
>> + T qa[5] = { T() };
>> + T i;
>> + T &j = i; // expected-note 4 {{'j' defined here}}
>> + S3 &p = k; // expected-note 2 {{'p' defined here}}
>> + const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
>> + T &q = qa[(int)i]; // expected-note 2 {{'q' defined here}}
>> + T fl; // expected-note {{'fl' defined here}}
>> + #pragma omp parallel reduction // expected-error {{expected '('
>> after 'reduction'}}
>> + foo();
>> + #pragma omp parallel reduction + // expected-error {{expected '('
>> after 'reduction'}} expected-warning {{extra tokens at the end of
>> '#pragma omp parallel' are ignored}}
>> + foo();
>> + #pragma omp parallel reduction ( // expected-error {{expected
>> unqualified-id}} expected-warning {{missing ':' after reduction
>> identifier - ignoring}} expected-error {{expected ')'}} expected-note
>> {{to match this '('}}
>> + foo();
>> + #pragma omp parallel reduction (- // expected-warning {{missing
>> ':' after reduction identifier - ignoring}} expected-error {{expected
>> expression}} expected-error {{expected ')'}} expected-note {{to match
>> this '('}}
>> + foo();
>> + #pragma omp parallel reduction () // expected-error {{expected
>> unqualified-id}} expected-warning {{missing ':' after reduction
>> identifier - ignoring}}
>> + foo();
>> + #pragma omp parallel reduction (*) // expected-warning {{missing
>> ':' after reduction identifier - ignoring}} expected-error {{expected
>> expression}}
>> + foo();
>> + #pragma omp parallel reduction (\) // expected-error {{expected
>> unqualified-id}} expected-warning {{missing ':' after reduction
>> identifier - ignoring}}
>> + foo();
>> + #pragma omp parallel reduction (&: argc // expected-error
>> {{expected ')'}} expected-note {{to match this '('}} expected-error
>> {{variable of type 'float' is not valid for specified reduction
>> operation}}
>> + foo();
>> + #pragma omp parallel reduction (| :argc, // expected-error
>> {{expected expression}} expected-error {{expected ')'}} expected-note
>> {{to match this '('}} expected-error {{variable of type 'float' is
>> not valid for specified reduction operation}}
>> + foo();
>> + #pragma omp parallel reduction (|| :argc ? i : argc) //
>> expected-error 2 {{expected variable name}}
>> + foo();
>> + #pragma omp parallel reduction (foo:argc) //expected-error
>> {{incorrect reduction identifier, expected one of '+', '-', '*', '&',
>> '|', '^', '&&', '||', 'min' or 'max'}}
>> + foo();
>> + #pragma omp parallel reduction (&& :argc)
>> + foo();
>> + #pragma omp parallel reduction (^ : T) // expected-error {{'T'
>> does not refer to a value}}
>> + foo();
>> + #pragma omp parallel reduction (+ : a, b, c, d, f) //
>> expected-error {{reduction variable with incomplete type 'S1'}}
>> expected-error 3 {{const-qualified variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel reduction (min : a, b, c, d, f) //
>> expected-error {{reduction variable with incomplete type 'S1'}}
>> expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min'
>> or 'max' must be of arithmetic type}} expected-error 3
>> {{const-qualified variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel reduction (max : qa[1]) // expected-error 2
>> {{expected variable name}}
>> + foo();
>> + #pragma omp parallel reduction(+ : ba) // expected-error {{a
>> reduction variable with array type 'const S2 [5]'}}
>> + foo();
>> + #pragma omp parallel reduction(* : ca) // expected-error {{a
>> reduction variable with array type 'const S3 [5]'}}
>> + foo();
>> + #pragma omp parallel reduction(- : da) // expected-error {{a
>> reduction variable with array type 'const int [5]'}} expected-error
>> {{a reduction variable with array type 'const float [5]'}}
>> + foo();
>> + #pragma omp parallel reduction(^ : fl) // expected-error
>> {{variable of type 'float' is not valid for specified reduction
>> operation}}
>> + foo();
>> + #pragma omp parallel reduction(&& : S2::S2s) // expected-error
>> {{shared variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel reduction(&& : S2::S2sc) // expected-error
>> {{const-qualified variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel reduction(+ : h, k) // expected-error
>> {{threadprivate or thread local variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel reduction(+ : o) // expected-error {{variable
>> of type 'class S6' is not valid for specified reduction operation}}
>> + foo();
>> + #pragma omp parallel private(i), reduction(+ : j), reduction(+:q)
>> // expected-error 4 {{argument of OpenMP clause 'reduction' must
>> reference the same object in all threads}}
>> + foo();
>> + #pragma omp parallel private(k)
>> + #pragma omp parallel reduction(+ : p), reduction(+ : p) //
>> expected-error 2 {{argument of OpenMP clause 'reduction' must
>> reference the same object in all threads}}
>> + foo();
>> + #pragma omp parallel reduction(+ : p), reduction(+ : p) //
>> expected-error 3 {{variable can appear only once in OpenMP
>> 'reduction' clause}} expected-note 3 {{previously referenced here}}
>> + foo();
>> + #pragma omp parallel reduction(+ : r) // expected-error 2
>> {{const-qualified variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel shared(i)
>> + #pragma omp parallel reduction(min : i)
>> + #pragma omp parallel reduction(max : j) // expected-error 2
>> {{argument of OpenMP clause 'reduction' must reference the same
>> object in all threads}}
>> + foo();
>> +
>> + return T();
>> +}
>> +
>> +int main(int argc, char **argv) {
>> + const int d = 5; // expected-note 2 {{'d' defined here}}
>> + const int da[5] = { 0 }; // expected-note {{'da' defined here}}
>> + int qa[5] = { 0 };
>> + S4 e(4); // expected-note {{'e' defined here}}
>> + S5 g(5); // expected-note {{'g' defined here}}
>> + int i;
>> + int &j = i; // expected-note 2 {{'j' defined here}}
>> + S3 &p = k; // expected-note 2 {{'p' defined here}}
>> + const int &r = da[i]; // expected-note {{'r' defined here}}
>> + int &q = qa[i]; // expected-note {{'q' defined here}}
>> + float fl; // expected-note {{'fl' defined here}}
>> + #pragma omp parallel reduction // expected-error {{expected '('
>> after 'reduction'}}
>> + foo();
>> + #pragma omp parallel reduction + // expected-error {{expected '('
>> after 'reduction'}} expected-warning {{extra tokens at the end of
>> '#pragma omp parallel' are ignored}}
>> + foo();
>> + #pragma omp parallel reduction ( // expected-error {{expected
>> unqualified-id}} expected-warning {{missing ':' after reduction
>> identifier - ignoring}} expected-error {{expected ')'}} expected-note
>> {{to match this '('}}
>> + foo();
>> + #pragma omp parallel reduction (- // expected-warning {{missing
>> ':' after reduction identifier - ignoring}} expected-error {{expected
>> expression}} expected-error {{expected ')'}} expected-note {{to match
>> this '('}}
>> + foo();
>> + #pragma omp parallel reduction () // expected-error {{expected
>> unqualified-id}} expected-warning {{missing ':' after reduction
>> identifier - ignoring}}
>> + foo();
>> + #pragma omp parallel reduction (*) // expected-warning {{missing
>> ':' after reduction identifier - ignoring}} expected-error {{expected
>> expression}}
>> + foo();
>> + #pragma omp parallel reduction (\) // expected-error {{expected
>> unqualified-id}} expected-warning {{missing ':' after reduction
>> identifier - ignoring}}
>> + foo();
>> + #pragma omp parallel reduction (foo: argc // expected-error
>> {{expected ')'}} expected-note {{to match this '('}} expected-error
>> {{incorrect reduction identifier, expected one of '+', '-', '*', '&',
>> '|', '^', '&&', '||', 'min' or 'max'}}
>> + foo();
>> + #pragma omp parallel reduction (| :argc, // expected-error
>> {{expected expression}} expected-error {{expected ')'}} expected-note
>> {{to match this '('}}
>> + foo();
>> + #pragma omp parallel reduction (|| :argc > 0 ? argv[1] : argv[2])
>> // expected-error {{expected variable name}}
>> + foo();
>> + #pragma omp parallel reduction (~:argc) // expected-error
>> {{expected unqualified-id}}
>> + foo();
>> + #pragma omp parallel reduction (&& :argc)
>> + foo();
>> + #pragma omp parallel reduction (^ : S1) // expected-error {{'S1'
>> does not refer to a value}}
>> + foo();
>> + #pragma omp parallel reduction (+ : a, b, c, d, f) //
>> expected-error {{reduction variable with incomplete type 'S1'}}
>> expected-error 2 {{const-qualified variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel reduction (min : a, b, c, d, f) //
>> expected-error {{reduction variable with incomplete type 'S1'}}
>> expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min'
>> or 'max' must be of arithmetic type}} expected-error 2
>> {{const-qualified variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel reduction (max : argv[1]) // expected-error
>> {{expected variable name}}
>> + foo();
>> + #pragma omp parallel reduction(+ : ba) // expected-error {{a
>> reduction variable with array type 'const S2 [5]'}}
>> + foo();
>> + #pragma omp parallel reduction(* : ca) // expected-error {{a
>> reduction variable with array type 'const S3 [5]'}}
>> + foo();
>> + #pragma omp parallel reduction(- : da) // expected-error {{a
>> reduction variable with array type 'const int [5]'}}
>> + foo();
>> + #pragma omp parallel reduction(^ : fl) // expected-error
>> {{variable of type 'float' is not valid for specified reduction
>> operation}}
>> + foo();
>> + #pragma omp parallel reduction(&& : S2::S2s) // expected-error
>> {{shared variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel reduction(&& : S2::S2sc) // expected-error
>> {{const-qualified variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel reduction(& : e, g) // expected-error
>> {{reduction variable must have an accessible, unambiguous default
>> constructor}} expected-error {{variable of type 'S5' is not valid for
>> specified reduction operation}}
>> + foo();
>> + #pragma omp parallel reduction(+ : h, k) // expected-error
>> {{threadprivate or thread local variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel reduction(+ : o) // expected-error {{variable
>> of type 'class S6' is not valid for specified reduction operation}}
>> + foo();
>> + #pragma omp parallel private(i), reduction(+ : j), reduction(+:q)
>> // expected-error 2 {{argument of OpenMP clause 'reduction' must
>> reference the same object in all threads}}
>> + foo();
>> + #pragma omp parallel private(k)
>> + #pragma omp parallel reduction(+ : p), reduction(+ : p) //
>> expected-error 2 {{argument of OpenMP clause 'reduction' must
>> reference the same object in all threads}}
>> + foo();
>> + #pragma omp parallel reduction(+ : p), reduction(+ : p) //
>> expected-error {{variable can appear only once in OpenMP 'reduction'
>> clause}} expected-note {{previously referenced here}}
>> + foo();
>> + #pragma omp parallel reduction(+ : r) // expected-error
>> {{const-qualified variable cannot be reduction}}
>> + foo();
>> + #pragma omp parallel shared(i)
>> + #pragma omp parallel reduction(min : i)
>> + #pragma omp parallel reduction(max : j) // expected-error
>> {{argument of OpenMP clause 'reduction' must reference the same
>> object in all threads}}
>> + foo();
>> +
>> + return tmain(argc) + tmain(fl); // expected-note {{in
>> instantiation of function template specialization 'tmain<int>'
>> requested here}} expected-note {{in instantiation of function
>> template specialization 'tmain<float>' requested here}}
>> +}
>>
>> Propchange: cfe/trunk/test/OpenMP/parallel_reduction_messages.cpp
>> ------------------------------------------------------------------------------
>>
>> svn:eol-style = native
>>
>> Propchange: cfe/trunk/test/OpenMP/parallel_reduction_messages.cpp
>> ------------------------------------------------------------------------------
>>
>> svn:keywords = Author Date Id Rev URL
>>
>> Propchange: cfe/trunk/test/OpenMP/parallel_reduction_messages.cpp
>> ------------------------------------------------------------------------------
>>
>> svn:mime-type = text/plain
>>
>> Modified: cfe/trunk/test/OpenMP/simd_aligned_messages.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/simd_aligned_messages.cpp?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/test/OpenMP/simd_aligned_messages.cpp (original)
>> +++ cfe/trunk/test/OpenMP/simd_aligned_messages.cpp Mon Jun 16
>> 02:08:35 2014
>> @@ -52,13 +52,14 @@ template<int L, class T, class N> T test
>> // expected-error at +1 {{argument to 'aligned' clause must be a
>> positive integer value}}
>> #pragma omp simd aligned(arr:L)
>> for (i = 0; i < num; ++i) {
>> - T cur = arr[ind2];
>> + T cur = arr[(int)ind2];
>> ind2 += L;
>> sum += cur;
>> }
>> // expected-error at +1 {{argument of aligned clause should be
>> array, pointer, reference to array or reference to pointer, not 'int'}}
>> #pragma omp simd aligned(num:4)
>> for (i = 0; i < num; ++i);
>> + return T();
>> }
>> template<int LEN> int test_warn() {
>>
>> 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=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/test/OpenMP/simd_linear_messages.cpp (original)
>> +++ cfe/trunk/test/OpenMP/simd_linear_messages.cpp Mon Jun 16
>> 02:08:35 2014
>> @@ -50,10 +50,11 @@ template<int L, class T, class N> T test
>> // expected-error at +1 {{argument of a linear clause should be of
>> integral or pointer type}}
>> #pragma omp simd linear(ind2:L)
>> for (i = 0; i < num; ++i) {
>> - T cur = arr[ind2];
>> + T cur = arr[(int)ind2];
>> ind2 += L;
>> sum += cur;
>> }
>> + return T();
>> }
>> template<int LEN> int test_warn() {
>>
>> Modified: cfe/trunk/tools/libclang/CIndex.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=211007&r1=211006&r2=211007&view=diff
>>
>> ==============================================================================
>>
>> --- cfe/trunk/tools/libclang/CIndex.cpp (original)
>> +++ cfe/trunk/tools/libclang/CIndex.cpp Mon Jun 16 02:08:35 2014
>> @@ -1963,6 +1963,9 @@ void OMPClauseEnqueue::VisitOMPLastpriva
>> void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause
>> *C) {
>> VisitOMPClauseList(C);
>> }
>> +void OMPClauseEnqueue::VisitOMPReductionClause(const
>> OMPReductionClause *C) {
>> + VisitOMPClauseList(C);
>> +}
>> void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause
>> *C) {
>> VisitOMPClauseList(C);
>> Visitor->AddStmt(C->getStep());
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list