Index: clang/include/clang/AST/OpenMPClause.h =================================================================== --- clang/include/clang/AST/OpenMPClause.h +++ clang/include/clang/AST/OpenMPClause.h @@ -859,6 +859,85 @@ } }; +/// This represents 'atomic_default_mem_order' clause in the '#pragma omp +/// requires' directive. +/// +/// \code +/// #pragma omp requires atomic_default_mem_order(seq_cst) +/// \endcode +/// In this example directive '#pragma omp requires' has simple +/// atomic_default_mem_order' clause with kind 'seq_cst'. +class OMPAtomicDefaultMemOrderClause final : public OMPClause { + friend class OMPClauseReader; + + /// Location of '(' + SourceLocation LParenLoc; + + /// A kind of the 'atomic_default_mem_order' clause. + OpenMPAtomicDefaultMemOrderClauseKind Kind = + OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown; + + /// Start location of the kind in source code. + SourceLocation KindKwLoc; + + /// Set kind of the clause. + /// + /// \param K Kind of clause. + void setAtomicDefaultMemOrderKind(OpenMPAtomicDefaultMemOrderClauseKind K) { + Kind = K; + } + + /// Set clause kind location. + /// + /// \param KLoc Kind location. + void setAtomicDefaultMemOrderKindKwLoc(SourceLocation KLoc) { + KindKwLoc = KLoc; + } + +public: + /// Build 'atomic_default_mem_order' clause with argument \a A ('seq_cst', + /// 'acq_rel' or 'relaxed'). + /// + /// \param A Argument of the clause ('seq_cst', 'acq_rel' or 'relaxed'). + /// \param ALoc Starting location of the argument. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + OMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind A, + SourceLocation ALoc, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_atomic_default_mem_order, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} + + /// Build an empty clause. + OMPAtomicDefaultMemOrderClause() + : OMPClause(OMPC_atomic_default_mem_order, SourceLocation(), + SourceLocation()) {} + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + + /// Returns the locaiton of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns kind of the clause. + OpenMPAtomicDefaultMemOrderClauseKind getAtomicDefaultMemOrderKind() const { + return Kind; + } + + /// Returns location of clause kind. + SourceLocation getAtomicDefaultMemOrderKindKwLoc() const { return KindKwLoc; } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_atomic_default_mem_order; + } +}; + /// This represents 'schedule' clause in the '#pragma omp ...' directive. /// /// \code Index: clang/include/clang/AST/RecursiveASTVisitor.h =================================================================== --- clang/include/clang/AST/RecursiveASTVisitor.h +++ clang/include/clang/AST/RecursiveASTVisitor.h @@ -2886,6 +2886,12 @@ } template +bool RecursiveASTVisitor::VisitOMPAtomicDefaultMemOrderClause( + OMPAtomicDefaultMemOrderClause *) { + return true; +} + +template bool RecursiveASTVisitor::VisitOMPScheduleClause(OMPScheduleClause *C) { TRY_TO(VisitOMPClauseWithPreInit(C)); Index: clang/include/clang/Basic/OpenMPKinds.h =================================================================== --- clang/include/clang/Basic/OpenMPKinds.h +++ clang/include/clang/Basic/OpenMPKinds.h @@ -120,6 +120,14 @@ OMPC_DEFAULTMAP_MODIFIER_last }; +/// OpenMP attributes for 'atomic_default_mem_order' clause. +enum OpenMPAtomicDefaultMemOrderClauseKind { +#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \ + OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown +}; + /// Scheduling data for loop-based OpenMP directives. struct OpenMPScheduleTy final { OpenMPScheduleClauseKind Schedule = OMPC_SCHEDULE_unknown; Index: clang/include/clang/Basic/OpenMPKinds.def =================================================================== --- clang/include/clang/Basic/OpenMPKinds.def +++ clang/include/clang/Basic/OpenMPKinds.def @@ -126,6 +126,9 @@ #ifndef OPENMP_DEFAULTMAP_KIND #define OPENMP_DEFAULTMAP_KIND(Name) #endif +#ifndef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND +#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) +#endif #ifndef OPENMP_DEFAULTMAP_MODIFIER #define OPENMP_DEFAULTMAP_MODIFIER(Name) #endif @@ -283,6 +286,7 @@ OPENMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause) OPENMP_CLAUSE(reverse_offload, OMPReverseOffloadClause) OPENMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause) +OPENMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause) // Clauses allowed for OpenMP directive 'parallel'. OPENMP_PARALLEL_CLAUSE(if) @@ -469,6 +473,12 @@ OPENMP_REQUIRES_CLAUSE(unified_shared_memory) OPENMP_REQUIRES_CLAUSE(reverse_offload) OPENMP_REQUIRES_CLAUSE(dynamic_allocators) +OPENMP_REQUIRES_CLAUSE(atomic_default_mem_order) + +// Modifiers for 'atomic_default_mem_order' clause. +OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst) +OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel) +OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(relaxed) // Clauses allowed for OpenMP directive 'target data'. OPENMP_TARGET_DATA_CLAUSE(if) @@ -898,6 +908,7 @@ #undef OPENMP_ATOMIC_CLAUSE #undef OPENMP_TARGET_CLAUSE #undef OPENMP_REQUIRES_CLAUSE +#undef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND #undef OPENMP_TARGET_DATA_CLAUSE #undef OPENMP_TARGET_ENTER_DATA_CLAUSE #undef OPENMP_TARGET_EXIT_DATA_CLAUSE Index: clang/include/clang/Sema/Sema.h =================================================================== --- clang/include/clang/Sema/Sema.h +++ clang/include/clang/Sema/Sema.h @@ -9195,6 +9195,11 @@ OMPClause *ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc); + /// Called on well-formed 'atomic_default_mem_order' clause. + OMPClause *ActOnOpenMPAtomicDefaultMemOrderClause( + OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + OMPClause *ActOnOpenMPVarListClause( OpenMPClauseKind Kind, ArrayRef Vars, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, Index: clang/lib/AST/DeclPrinter.cpp =================================================================== --- clang/lib/AST/DeclPrinter.cpp +++ clang/lib/AST/DeclPrinter.cpp @@ -1549,11 +1549,9 @@ void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) { Out << "#pragma omp requires "; if (!D->clauselist_empty()) { - for (auto I = D->clauselist_begin(), E = D->clauselist_end(); I != E; ++I) { - if (I != D->clauselist_begin()) - Out << ','; - Out << getOpenMPClauseName((*I)->getClauseKind()); - } + OMPClausePrinter Printer(Out, Policy); + for (auto I = D->clauselist_begin(), E = D->clauselist_end(); I != E; ++I) + Printer.Visit(*I); } } Index: clang/lib/AST/OpenMPClause.cpp =================================================================== --- clang/lib/AST/OpenMPClause.cpp +++ clang/lib/AST/OpenMPClause.cpp @@ -111,6 +111,7 @@ case OMPC_unified_shared_memory: case OMPC_reverse_offload: case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: break; } @@ -184,6 +185,7 @@ case OMPC_unified_shared_memory: case OMPC_reverse_offload: case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: break; } @@ -1123,6 +1125,14 @@ OS << "dynamic_allocators"; } +void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause( + OMPAtomicDefaultMemOrderClause *Node) { + OS << "atomic_default_mem_order(" + << getOpenMPSimpleClauseTypeName(OMPC_atomic_default_mem_order, + Node->getAtomicDefaultMemOrderKind()) + << ")"; +} + void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) { OS << "schedule("; if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) { Index: clang/lib/AST/StmtProfile.cpp =================================================================== --- clang/lib/AST/StmtProfile.cpp +++ clang/lib/AST/StmtProfile.cpp @@ -479,6 +479,9 @@ void OMPClauseProfiler::VisitOMPDynamicAllocatorsClause( const OMPDynamicAllocatorsClause *C) {} +void OMPClauseProfiler::VisitOMPAtomicDefaultMemOrderClause( + const OMPAtomicDefaultMemOrderClause *C) {} + void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) { VistOMPClauseWithPreInit(C); if (auto *S = C->getChunkSize()) Index: clang/lib/Basic/OpenMPKinds.cpp =================================================================== --- clang/lib/Basic/OpenMPKinds.cpp +++ clang/lib/Basic/OpenMPKinds.cpp @@ -125,6 +125,12 @@ .Case(#Name, static_cast(OMPC_DEFAULTMAP_MODIFIER_##Name)) #include "clang/Basic/OpenMPKinds.def" .Default(OMPC_DEFAULTMAP_unknown); + case OMPC_atomic_default_mem_order: + return llvm::StringSwitch(Str) +#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \ + .Case(#Name, OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: @@ -270,6 +276,16 @@ #include "clang/Basic/OpenMPKinds.def" } llvm_unreachable("Invalid OpenMP 'schedule' clause type"); + case OMPC_atomic_default_mem_order: + switch (Type) { + case OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown: + return "unknown"; +#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \ + case OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name: \ + return #Name; +#include "clang/Basic/OpenMPKinds.def" +} + llvm_unreachable("Invalid OpenMP 'atomic_default_mem_order' clause type"); case OMPC_unknown: case OMPC_threadprivate: case OMPC_if: Index: clang/lib/CodeGen/CGStmtOpenMP.cpp =================================================================== --- clang/lib/CodeGen/CGStmtOpenMP.cpp +++ clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -3902,6 +3902,7 @@ case OMPC_unified_shared_memory: case OMPC_reverse_offload: case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: llvm_unreachable("Clause is not allowed in 'omp atomic'."); } } Index: clang/lib/Parse/ParseOpenMP.cpp =================================================================== --- clang/lib/Parse/ParseOpenMP.cpp +++ clang/lib/Parse/ParseOpenMP.cpp @@ -1337,11 +1337,15 @@ break; case OMPC_default: case OMPC_proc_bind: + case OMPC_atomic_default_mem_order: // OpenMP [2.14.3.1, Restrictions] // Only a single default clause may be specified on a parallel, task or // teams directive. // OpenMP [2.5, parallel Construct, Restrictions] // At most one proc_bind clause can appear on the directive. + // OpenMP [5.0, Requires directive, Restrictions] + // At most one atomic_default_mem_order clause can appear + // on the directive if (!FirstClause) { Diag(Tok, diag::err_omp_more_one_clause) << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; Index: clang/lib/Sema/SemaOpenMP.cpp =================================================================== --- clang/lib/Sema/SemaOpenMP.cpp +++ clang/lib/Sema/SemaOpenMP.cpp @@ -8014,6 +8014,7 @@ case OMPC_unified_shared_memory: case OMPC_reverse_offload: case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: llvm_unreachable("Clause is not allowed."); } return Res; @@ -8539,6 +8540,7 @@ case OMPC_unified_shared_memory: case OMPC_reverse_offload: case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: llvm_unreachable("Unexpected OpenMP clause."); } return CaptureRegion; @@ -8807,6 +8809,11 @@ static_cast(Argument), ArgumentLoc, StartLoc, LParenLoc, EndLoc); break; + case OMPC_atomic_default_mem_order: + Res = ActOnOpenMPAtomicDefaultMemOrderClause( + static_cast(Argument), + ArgumentLoc, StartLoc, LParenLoc, EndLoc); + break; case OMPC_if: case OMPC_final: case OMPC_num_threads: @@ -8932,6 +8939,21 @@ OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); } +OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( + OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { + if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { + Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) + << getListOfPossibleValues( + OMPC_atomic_default_mem_order, /*First=*/0, + /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) + << getOpenMPClauseName(OMPC_atomic_default_mem_order); + return nullptr; + } + return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, + LParenLoc, EndLoc); +} + OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( OpenMPClauseKind Kind, ArrayRef Argument, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -9020,6 +9042,7 @@ case OMPC_unified_shared_memory: case OMPC_reverse_offload: case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: llvm_unreachable("Clause is not allowed."); } return Res; @@ -9226,6 +9249,7 @@ case OMPC_from: case OMPC_use_device_ptr: case OMPC_is_device_ptr: + case OMPC_atomic_default_mem_order: llvm_unreachable("Clause is not allowed."); } return Res; @@ -9418,6 +9442,7 @@ case OMPC_unified_shared_memory: case OMPC_reverse_offload: case OMPC_dynamic_allocators: + case OMPC_atomic_default_mem_order: llvm_unreachable("Clause is not allowed."); } return Res; Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -8457,6 +8457,13 @@ } template +OMPClause *TreeTransform::TransformOMPAtomicDefaultMemOrderClause( + OMPAtomicDefaultMemOrderClause *C) { + llvm_unreachable( + "atomic_default_mem_order clause cannot appear in dependent context"); +} + +template OMPClause * TreeTransform::TransformOMPPrivateClause(OMPPrivateClause *C) { llvm::SmallVector Vars; Index: clang/lib/Serialization/ASTReader.cpp =================================================================== --- clang/lib/Serialization/ASTReader.cpp +++ clang/lib/Serialization/ASTReader.cpp @@ -11732,7 +11732,10 @@ case OMPC_dynamic_allocators: C = new (Context) OMPDynamicAllocatorsClause(); break; - case OMPC_private: + case OMPC_atomic_default_mem_order: + C = new (Context) OMPAtomicDefaultMemOrderClause(); + break; + case OMPC_private: C = OMPPrivateClause::CreateEmpty(Context, Record.readInt()); break; case OMPC_firstprivate: @@ -11971,6 +11974,14 @@ OMPClauseReader::VisitOMPDynamicAllocatorsClause(OMPDynamicAllocatorsClause *) { } +void OMPClauseReader::VisitOMPAtomicDefaultMemOrderClause( + OMPAtomicDefaultMemOrderClause *C) { + C->setAtomicDefaultMemOrderKind( + static_cast(Record.readInt())); + C->setLParenLoc(Record.readSourceLocation()); + C->setAtomicDefaultMemOrderKindKwLoc(Record.readSourceLocation()); +} + void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) { C->setLParenLoc(Record.readSourceLocation()); unsigned NumVars = C->varlist_size(); Index: clang/lib/Serialization/ASTWriter.cpp =================================================================== --- clang/lib/Serialization/ASTWriter.cpp +++ clang/lib/Serialization/ASTWriter.cpp @@ -6941,3 +6941,10 @@ void OMPClauseWriter::VisitOMPDynamicAllocatorsClause(OMPDynamicAllocatorsClause *) { } + +void OMPClauseWriter::VisitOMPAtomicDefaultMemOrderClause( + OMPAtomicDefaultMemOrderClause *C) { + Record.push_back(C->getAtomicDefaultMemOrderKind()); + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getAtomicDefaultMemOrderKindKwLoc()); +} Index: clang/test/OpenMP/requires_acq_rel_print.cpp =================================================================== --- /dev/null +++ clang/test/OpenMP/requires_acq_rel_print.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +#pragma omp requires atomic_default_mem_order(acq_rel) +// CHECK:#pragma omp requires atomic_default_mem_order(acq_rel) + +#endif Index: clang/test/OpenMP/requires_ast_print.cpp =================================================================== --- /dev/null +++ clang/test/OpenMP/requires_ast_print.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +#pragma omp requires unified_address +// CHECK:#pragma omp requires unified_address + +#pragma omp requires unified_shared_memory +// CHECK:#pragma omp requires unified_shared_memory + +#pragma omp requires reverse_offload +// CHECK:#pragma omp requires reverse_offload + +#pragma omp requires dynamic_allocators +// CHECK:#pragma omp requires dynamic_allocators + +#pragma omp requires atomic_default_mem_order(seq_cst) +// CHECK:#pragma omp requires atomic_default_mem_order(seq_cst) + +#endif Index: clang/test/OpenMP/requires_messages.cpp =================================================================== --- /dev/null +++ clang/test/OpenMP/requires_messages.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s + +#pragma omp requires unified_address // expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note{{unified_address clause previously used here}} + +#pragma omp requires unified_shared_memory // expected-note {{unified_shared_memory clause previously used here}} expected-note{{unified_shared_memory clause previously used here}} + +#pragma omp requires unified_shared_memory, unified_shared_memory // expected-error {{Only one unified_shared_memory clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_shared_memory' clause}} + +#pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} + +#pragma omp requires unified_address, unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_address' clause}} + +#pragma omp requires reverse_offload // expected-note {{reverse_offload clause previously used here}} expected-note {{reverse_offload clause previously used here}} + +#pragma omp requires reverse_offload, reverse_offload // expected-error {{Only one reverse_offload clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'reverse_offload' clause}} + +#pragma omp requires dynamic_allocators // expected-note {{dynamic_allocators clause previously used here}} expected-note {{dynamic_allocators clause previously used here}} + +#pragma omp requires dynamic_allocators, dynamic_allocators // expected-error {{Only one dynamic_allocators clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'dynamic_allocators' clause}} + +#pragma omp requires atomic_default_mem_order(seq_cst) // expected-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}} expected-note {{atomic_default_mem_order clause previously used here}} + +#pragma omp requires atomic_default_mem_order(acq_rel) // expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} + +#pragma omp requires atomic_default_mem_order(relaxed) // expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} + +#pragma omp requires atomic_default_mem_order // expected-error {{expected '(' after 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} + +#pragma omp requires atomic_default_mem_order( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} + +#pragma omp requires atomic_default_mem_order(seq_cst // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} + +#pragma omp requires atomic_default_mem_order(invalid_modifier) // expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} + +#pragma omp requires atomic_default_mem_order(shared) // expected-error {{expected 'seq_cst', 'acq_rel' or 'relaxed' in OpenMP clause 'atomic_default_mem_order'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} + +#pragma omp requires atomic_default_mem_order(acq_rel), atomic_default_mem_order(relaxed) // expected-error {{directive '#pragma omp requires' cannot contain more than one 'atomic_default_mem_order' claus}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} + +#pragma omp requires // expected-error {{expected at least one clause on '#pragma omp requires' directive}} + +#pragma omp requires invalid_clause // expected-warning {{extra tokens at the end of '#pragma omp requires' are ignored}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} + +#pragma omp requires nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp requires'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} + +#pragma omp requires unified_address, invalid_clause // expected-warning {{extra tokens at the end of '#pragma omp requires' are ignored}} expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} + +#pragma omp requires invalid_clause unified_address // expected-warning {{extra tokens at the end of '#pragma omp requires' are ignored}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} + +#pragma omp requires unified_shared_memory, unified_address, reverse_offload, dynamic_allocators, atomic_default_mem_order(seq_cst) // expected-error {{Only one unified_shared_memory clause can appear on a requires directive in a single translation unit}} expected-error{{Only one unified_address clause can appear on a requires directive in a single translation unit}} expected-error{{Only one reverse_offload clause can appear on a requires directive in a single translation unit}} expected-error{{Only one dynamic_allocators clause can appear on a requires directive in a single translation unit}} expected-error {{Only one atomic_default_mem_order clause can appear on a requires directive in a single translation unit}} + +namespace A { + #pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} + namespace B { + #pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} + } +} + +template T foo() { + #pragma omp requires unified_address // expected-error {{unexpected OpenMP directive '#pragma omp requires'}} +} + +class C { + #pragma omp requires unified_address // expected-error {{'#pragma omp requires' directive must appear only in file scope}} +}; + +int main() { + #pragma omp requires unified_address // expected-error {{unexpected OpenMP directive '#pragma omp requires'}} +} Index: clang/test/OpenMP/requires_relaxed_print.cpp =================================================================== --- /dev/null +++ clang/test/OpenMP/requires_relaxed_print.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s + +// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s +// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s +// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s +// expected-no-diagnostics + +#ifndef HEADER +#define HEADER + +#pragma omp requires atomic_default_mem_order(relaxed) +// CHECK:#pragma omp requires atomic_default_mem_order(relaxed) + +#endif Index: clang/test/OpenMP/requires_unified_address_ast_print.cpp =================================================================== --- clang/test/OpenMP/requires_unified_address_ast_print.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s - -// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s -// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s -// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s -// expected-no-diagnostics - -#ifndef HEADER -#define HEADER - -#pragma omp requires unified_address -// CHECK:#pragma omp requires unified_address - -#pragma omp requires unified_shared_memory -// CHECK:#pragma omp requires unified_shared_memory - -#pragma omp requires reverse_offload -// CHECK:#pragma omp requires reverse_offload - -#pragma omp requires dynamic_allocators -// CHECK:#pragma omp requires dynamic_allocators - -#endif Index: clang/test/OpenMP/requires_unified_address_messages.cpp =================================================================== --- clang/test/OpenMP/requires_unified_address_messages.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s - -#pragma omp requires unified_address // expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note {{unified_address clause previously used here}} expected-note{{unified_address clause previously used here}} - -#pragma omp requires unified_shared_memory // expected-note {{unified_shared_memory clause previously used here}} expected-note{{unified_shared_memory clause previously used here}} - -#pragma omp requires unified_shared_memory, unified_shared_memory // expected-error {{Only one unified_shared_memory clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_shared_memory' clause}} - -#pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} - -#pragma omp requires unified_address, unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'unified_address' clause}} - -#pragma omp requires reverse_offload // expected-note {{reverse_offload clause previously used here}} expected-note {{reverse_offload clause previously used here}} - -#pragma omp requires reverse_offload, reverse_offload // expected-error {{Only one reverse_offload clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'reverse_offload' clause}} - -#pragma omp requires dynamic_allocators // expected-note {{dynamic_allocators clause previously used here}} expected-note {{dynamic_allocators clause previously used here}} - -#pragma omp requires dynamic_allocators, dynamic_allocators // expected-error {{Only one dynamic_allocators clause can appear on a requires directive in a single translation unit}} expected-error {{directive '#pragma omp requires' cannot contain more than one 'dynamic_allocators' clause}} - - -#pragma omp requires // expected-error {{expected at least one clause on '#pragma omp requires' directive}} - -#pragma omp requires invalid_clause // expected-warning {{extra tokens at the end of '#pragma omp requires' are ignored}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} - -#pragma omp requires nowait // expected-error {{unexpected OpenMP clause 'nowait' in directive '#pragma omp requires'}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} - -#pragma omp requires unified_address, invalid_clause // expected-warning {{extra tokens at the end of '#pragma omp requires' are ignored}} expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} - -#pragma omp requires invalid_clause unified_address // expected-warning {{extra tokens at the end of '#pragma omp requires' are ignored}} expected-error {{expected at least one clause on '#pragma omp requires' directive}} - -#pragma omp requires unified_shared_memory, unified_address, reverse_offload, dynamic_allocators // expected-error {{Only one unified_shared_memory clause can appear on a requires directive in a single translation unit}} expected-error{{Only one unified_address clause can appear on a requires directive in a single translation unit}} expected-error{{Only one reverse_offload clause can appear on a requires directive in a single translation unit}} expected-error{{Only one dynamic_allocators clause can appear on a requires directive in a single translation unit}} - -namespace A { - #pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} - namespace B { - #pragma omp requires unified_address // expected-error {{Only one unified_address clause can appear on a requires directive in a single translation unit}} - } -} - -template T foo() { - #pragma omp requires unified_address // expected-error {{unexpected OpenMP directive '#pragma omp requires'}} -} - -class C { - #pragma omp requires unified_address // expected-error {{'#pragma omp requires' directive must appear only in file scope}} -}; - -int main() { - #pragma omp requires unified_address // expected-error {{unexpected OpenMP directive '#pragma omp requires'}} -} Index: clang/tools/libclang/CIndex.cpp =================================================================== --- clang/tools/libclang/CIndex.cpp +++ clang/tools/libclang/CIndex.cpp @@ -2219,6 +2219,9 @@ void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause( const OMPDynamicAllocatorsClause *) {} +void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause( + const OMPAtomicDefaultMemOrderClause *) {} + void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) { Visitor->AddStmt(C->getDevice()); }