summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/DeclOpenMP.h71
-rw-r--r--clang/include/clang/AST/OpenMPClause.h31
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h12
-rw-r--r--clang/include/clang/Basic/DeclNodes.td1
-rw-r--r--clang/include/clang/Basic/DiagnosticParseKinds.td2
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td6
-rw-r--r--clang/include/clang/Basic/OpenMPKinds.def9
-rw-r--r--clang/include/clang/Sema/Sema.h12
-rw-r--r--clang/include/clang/Serialization/ASTBitCodes.h3
-rw-r--r--clang/lib/AST/ASTDumper.cpp21
-rw-r--r--clang/lib/AST/DeclBase.cpp1
-rw-r--r--clang/lib/AST/DeclOpenMP.cpp32
-rw-r--r--clang/lib/AST/DeclPrinter.cpp15
-rw-r--r--clang/lib/AST/OpenMPClause.cpp2
-rw-r--r--clang/lib/AST/StmtPrinter.cpp4
-rw-r--r--clang/lib/AST/StmtProfile.cpp3
-rw-r--r--clang/lib/Basic/OpenMPKinds.cpp13
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp5
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp2
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp4
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp1
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h4
-rw-r--r--clang/lib/Parse/ParseOpenMP.cpp48
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp78
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp5
-rw-r--r--clang/lib/Sema/TreeTransform.h6
-rw-r--r--clang/lib/Serialization/ASTCommon.cpp1
-rw-r--r--clang/lib/Serialization/ASTReader.cpp5
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp16
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp2
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp11
-rw-r--r--clang/test/OpenMP/requires_unified_address_ast_print.cpp16
-rw-r--r--clang/test/OpenMP/requires_unified_address_messages.cpp36
-rw-r--r--clang/tools/libclang/CIndex.cpp4
35 files changed, 483 insertions, 3 deletions
diff --git a/clang/include/clang/AST/DeclOpenMP.h b/clang/include/clang/AST/DeclOpenMP.h
index 33fe0e196dc..8540cc5b25b 100644
--- a/clang/include/clang/AST/DeclOpenMP.h
+++ b/clang/include/clang/AST/DeclOpenMP.h
@@ -18,6 +18,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Type.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/TrailingObjects.h"
@@ -239,6 +240,76 @@ public:
static bool classofKind(Kind K) { return K == OMPCapturedExpr; }
};
+/// This represents '#pragma omp requires...' directive.
+/// For example
+///
+/// \code
+/// #pragma omp requires unified_address
+/// \endcode
+///
+class OMPRequiresDecl final
+ : public Decl,
+ private llvm::TrailingObjects<OMPRequiresDecl, OMPClause *> {
+ friend class ASTDeclReader;
+ friend TrailingObjects;
+
+ // Number of clauses associated with this requires declaration
+ unsigned NumClauses = 0;
+
+ virtual void anchor();
+
+ OMPRequiresDecl(Kind DK, DeclContext *DC, SourceLocation L)
+ : Decl(DK, DC, L), NumClauses(0) {}
+
+ /// Returns an array of immutable clauses associated with this requires
+ /// declaration
+ ArrayRef<const OMPClause *> getClauses() const {
+ return llvm::makeArrayRef(getTrailingObjects<OMPClause *>(), NumClauses);
+ }
+
+ /// Returns an array of clauses associated with this requires declaration
+ MutableArrayRef<OMPClause *> getClauses() {
+ return MutableArrayRef<OMPClause *>(getTrailingObjects<OMPClause *>(),
+ NumClauses);
+ }
+
+ /// Sets an array of clauses to this requires declaration
+ void setClauses(ArrayRef<OMPClause *> CL);
+
+public:
+ /// Create requires node.
+ static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, ArrayRef<OMPClause *> CL);
+ /// Create deserialized requires node.
+ static OMPRequiresDecl *CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned N);
+
+ using clauselist_iterator = MutableArrayRef<OMPClause *>::iterator;
+ using clauselist_const_iterator = ArrayRef<const OMPClause *>::iterator;
+ using clauselist_range = llvm::iterator_range<clauselist_iterator>;
+ using clauselist_const_range = llvm::iterator_range<clauselist_const_iterator>;
+
+ unsigned clauselist_size() const { return NumClauses; }
+ bool clauselist_empty() const { return NumClauses == 0; }
+
+ clauselist_range clauselists() {
+ return clauselist_range(clauselist_begin(), clauselist_end());
+ }
+ clauselist_const_range clauselists() const {
+ return clauselist_const_range(clauselist_begin(), clauselist_end());
+ }
+ clauselist_iterator clauselist_begin() { return getClauses().begin(); }
+ clauselist_iterator clauselist_end() { return getClauses().end(); }
+ clauselist_const_iterator clauselist_begin() const {
+ return getClauses().begin();
+ }
+ clauselist_const_iterator clauselist_end() const {
+ return getClauses().end();
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) { return K == OMPRequires; }
+};
} // end namespace clang
#endif
diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h
index 77118cc3f4a..6a2c806bb63 100644
--- a/clang/include/clang/AST/OpenMPClause.h
+++ b/clang/include/clang/AST/OpenMPClause.h
@@ -734,6 +734,37 @@ public:
}
};
+/// This represents 'unified_address' clause in the '#pragma omp requires'
+/// directive.
+///
+/// \code
+/// #pragma omp requires unified_address
+/// \endcode
+/// In this example directive '#pragma omp requires' has 'unified_address'
+/// clause.
+class OMPUnifiedAddressClause final : public OMPClause {
+public:
+ friend class OMPClauseReader;
+ /// Build 'unified_address' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_unified_address, StartLoc, EndLoc) {}
+
+ /// Build an empty clause.
+ OMPUnifiedAddressClause()
+ : OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {}
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_unified_address;
+ }
+};
+
/// This represents 'schedule' clause in the '#pragma omp ...' directive.
///
/// \code
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 0d2b670507c..d4a578114d7 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1589,6 +1589,12 @@ DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
for (auto *I : D->varlists()) {
TRY_TO(TraverseStmt(I));
}
+ })
+
+DEF_TRAVERSE_DECL(OMPRequiresDecl, {
+ for (auto *C : D->clauselists()) {
+ TRY_TO(TraverseOMPClause(C));
+ }
})
DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, {
@@ -2854,6 +2860,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedAddressClause(
+ OMPUnifiedAddressClause *) {
+ return true;
+}
+
+template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
TRY_TO(VisitOMPClauseWithPreInit(C));
diff --git a/clang/include/clang/Basic/DeclNodes.td b/clang/include/clang/Basic/DeclNodes.td
index 67ca9e5c6c6..a184b480f7c 100644
--- a/clang/include/clang/Basic/DeclNodes.td
+++ b/clang/include/clang/Basic/DeclNodes.td
@@ -97,5 +97,6 @@ def Captured : Decl, DeclContext;
def ClassScopeFunctionSpecialization : Decl;
def Import : Decl;
def OMPThreadPrivate : Decl;
+def OMPRequires : Decl;
def Empty : Decl;
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 609dca4f075..8da6e157258 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1125,6 +1125,8 @@ def err_expected_end_declare_target : Error<
"expected '#pragma omp end declare target'">;
def err_omp_declare_target_unexpected_clause: Error<
"unexpected '%0' clause, only 'to' or 'link' clauses expected">;
+def err_omp_expected_clause: Error<
+ "expected at least one clause on '#pragma omp %0' directive">;
// Pragma loop support.
def err_pragma_loop_missing_argument : Error<
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 936cc79d605..6f0014ce186 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9073,6 +9073,12 @@ def err_omp_linear_distribute_var_non_loop_iteration : Error<
def warn_omp_non_trivial_type_mapped : Warning<
"Non-trivial type %0 is mapped, only trivial types are guaranteed to be mapped correctly">,
InGroup<OpenMPTarget>;
+def err_omp_requires_clause_redeclaration : Error <
+ "Only one %0 clause can appear on a requires directive in a single translation unit">;
+def note_omp_requires_previous_clause : Note <
+ "%0 clause previously used here">;
+def err_omp_invalid_scope : Error <
+ "'#pragma omp %0' directive must appear only in file scope">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def
index 4ed7053b679..8ad40d68a4a 100644
--- a/clang/include/clang/Basic/OpenMPKinds.def
+++ b/clang/include/clang/Basic/OpenMPKinds.def
@@ -57,6 +57,9 @@
#ifndef OPENMP_TARGET_CLAUSE
# define OPENMP_TARGET_CLAUSE(Name)
#endif
+#ifndef OPENMP_REQUIRES_CLAUSE
+# define OPENMP_REQUIRES_CLAUSE(Name)
+#endif
#ifndef OPENMP_TARGET_DATA_CLAUSE
# define OPENMP_TARGET_DATA_CLAUSE(Name)
#endif
@@ -193,6 +196,7 @@ OPENMP_DIRECTIVE(atomic)
OPENMP_DIRECTIVE(target)
OPENMP_DIRECTIVE(teams)
OPENMP_DIRECTIVE(cancel)
+OPENMP_DIRECTIVE(requires)
OPENMP_DIRECTIVE_EXT(target_data, "target data")
OPENMP_DIRECTIVE_EXT(target_enter_data, "target enter data")
OPENMP_DIRECTIVE_EXT(target_exit_data, "target exit data")
@@ -275,6 +279,7 @@ OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause)
OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause)
OPENMP_CLAUSE(task_reduction, OMPTaskReductionClause)
OPENMP_CLAUSE(in_reduction, OMPInReductionClause)
+OPENMP_CLAUSE(unified_address, OMPUnifiedAddressClause)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
@@ -456,6 +461,9 @@ OPENMP_TARGET_CLAUSE(firstprivate)
OPENMP_TARGET_CLAUSE(is_device_ptr)
OPENMP_TARGET_CLAUSE(reduction)
+// Clauses allowed for OpenMP directive 'requires'.
+OPENMP_REQUIRES_CLAUSE(unified_address)
+
// Clauses allowed for OpenMP directive 'target data'.
OPENMP_TARGET_DATA_CLAUSE(if)
OPENMP_TARGET_DATA_CLAUSE(device)
@@ -883,6 +891,7 @@ OPENMP_TASKGROUP_CLAUSE(task_reduction)
#undef OPENMP_TASK_CLAUSE
#undef OPENMP_ATOMIC_CLAUSE
#undef OPENMP_TARGET_CLAUSE
+#undef OPENMP_REQUIRES_CLAUSE
#undef OPENMP_TARGET_DATA_CLAUSE
#undef OPENMP_TARGET_ENTER_DATA_CLAUSE
#undef OPENMP_TARGET_EXIT_DATA_CLAUSE
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index dfcc61fa370..d5447bf4381 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -153,6 +153,7 @@ namespace clang {
class ObjCPropertyDecl;
class ObjCProtocolDecl;
class OMPThreadPrivateDecl;
+ class OMPRequiresDecl;
class OMPDeclareReductionDecl;
class OMPDeclareSimdDecl;
class OMPClause;
@@ -8714,6 +8715,12 @@ public:
/// Builds a new OpenMPThreadPrivateDecl and checks its correctness.
OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl(SourceLocation Loc,
ArrayRef<Expr *> VarList);
+ /// Called on well-formed '#pragma omp requires'.
+ DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc,
+ ArrayRef<OMPClause *> ClauseList);
+ /// Check restrictions on Requires directive
+ OMPRequiresDecl *CheckOMPRequiresDecl(SourceLocation Loc,
+ ArrayRef<OMPClause *> Clauses);
/// Check if the specified type is allowed to be used in 'omp declare
/// reduction' construct.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
@@ -9107,7 +9114,7 @@ public:
SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc);
-
+
OMPClause *ActOnOpenMPSingleExprWithArgClause(
OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr,
SourceLocation StartLoc, SourceLocation LParenLoc,
@@ -9155,6 +9162,9 @@ public:
/// Called on well-formed 'nogroup' clause.
OMPClause *ActOnOpenMPNogroupClause(SourceLocation StartLoc,
SourceLocation EndLoc);
+ /// Called on well-formed 'unified_address' clause.
+ OMPClause *ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
+ SourceLocation EndLoc);
OMPClause *ActOnOpenMPVarListClause(
OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr,
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 430fc48379f..51a3999c1a8 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -1516,6 +1516,9 @@ namespace serialization {
/// An OMPThreadPrivateDecl record.
DECL_OMP_THREADPRIVATE,
+ /// An OMPRequiresDecl record.
+ DECL_OMP_REQUIRES,
+
/// An EmptyDecl record.
DECL_EMPTY,
diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp
index 2f08f58ade6..38a2fe9caf3 100644
--- a/clang/lib/AST/ASTDumper.cpp
+++ b/clang/lib/AST/ASTDumper.cpp
@@ -450,6 +450,7 @@ namespace {
// OpenMP decls
void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D);
+ void VisitOMPRequiresDecl(const OMPRequiresDecl *D);
void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D);
// C++ Decls
@@ -1340,6 +1341,26 @@ void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
}
}
+void ASTDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
+ for (auto *C : D->clauselists()) {
+ dumpChild([=] {
+ if (!C) {
+ ColorScope Color(*this, NullColor);
+ OS << "<<<NULL>>> OMPClause";
+ return;
+ }
+ {
+ ColorScope Color(*this, AttrColor);
+ StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
+ OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
+ << ClauseName.drop_front() << "Clause";
+ }
+ dumpPointer(C);
+ dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
+ });
+ }
+}
+
void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
dumpName(D);
dumpType(D->getType());
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index b706e504a3a..f5de3591065 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -810,6 +810,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ObjCCategoryImpl:
case Import:
case OMPThreadPrivate:
+ case OMPRequires:
case OMPCapturedExpr:
case Empty:
// Never looked up by name.
diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp
index d5afc27c5f5..b77a67cbf38 100644
--- a/clang/lib/AST/DeclOpenMP.cpp
+++ b/clang/lib/AST/DeclOpenMP.cpp
@@ -54,6 +54,38 @@ void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) {
}
//===----------------------------------------------------------------------===//
+// OMPRequiresDecl Implementation.
+//===----------------------------------------------------------------------===//
+
+void OMPRequiresDecl::anchor() {}
+
+OMPRequiresDecl *OMPRequiresDecl::Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L,
+ ArrayRef<OMPClause *> CL) {
+ OMPRequiresDecl *D =
+ new (C, DC, additionalSizeToAlloc<OMPClause *>(CL.size()))
+ OMPRequiresDecl(OMPRequires, DC, L);
+ D->NumClauses = CL.size();
+ D->setClauses(CL);
+ return D;
+}
+
+OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned N) {
+ OMPRequiresDecl *D = new (C, ID, additionalSizeToAlloc<OMPClause *>(N))
+ OMPRequiresDecl(OMPRequires, nullptr, SourceLocation());
+ D->NumClauses = N;
+ return D;
+}
+
+void OMPRequiresDecl::setClauses(ArrayRef<OMPClause *> CL) {
+ assert(CL.size() == NumClauses &&
+ "Number of clauses is not the same as the preallocated buffer");
+ std::uninitialized_copy(CL.begin(), CL.end(),
+ getTrailingObjects<OMPClause *>());
+}
+
+//===----------------------------------------------------------------------===//
// OMPDeclareReductionDecl Implementation.
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 9f4cfb261d7..7fc275f90e9 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -100,6 +100,7 @@ namespace {
void VisitUsingDecl(UsingDecl *D);
void VisitUsingShadowDecl(UsingShadowDecl *D);
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
+ void VisitOMPRequiresDecl(OMPRequiresDecl *D);
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
@@ -422,7 +423,8 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
// FIXME: Need to be able to tell the DeclPrinter when
const char *Terminator = nullptr;
- if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D))
+ if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D) ||
+ isa<OMPRequiresDecl>(*D))
Terminator = nullptr;
else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody())
Terminator = nullptr;
@@ -1544,6 +1546,17 @@ void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
}
}
+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());
+ }
+ }
+}
+
void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
if (!D->isInvalidDecl()) {
Out << "#pragma omp declare reduction (";
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 68550a5cf99..1114ae3e92e 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -106,6 +106,7 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_unified_address:
break;
}
@@ -175,6 +176,7 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_unified_address:
break;
}
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index d540fad51c6..fe6f3d0d348 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -698,6 +698,10 @@ void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
<< ")";
}
+void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {
+ OS << "unified_address";
+}
+
void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
OS << "schedule(";
if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 133ecf7cdc6..b97812345be 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -467,6 +467,9 @@ void OMPClauseProfiler::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
void OMPClauseProfiler::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
+void OMPClauseProfiler::VisitOMPUnifiedAddressClause(
+ const OMPUnifiedAddressClause *C) {}
+
void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
VistOMPClauseWithPreInit(C);
if (auto *S = C->getChunkSize())
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 67b7d91e629..2251d897542 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -168,6 +168,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_unified_address:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -309,6 +310,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_unified_address:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -442,6 +444,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
break;
}
break;
+ case OMPD_requires:
+ switch (CKind) {
+#define OPENMP_REQUIRES_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
case OMPD_target_data:
switch (CKind) {
#define OPENMP_TARGET_DATA_CLAUSE(Name) \
@@ -961,6 +973,7 @@ void clang::getOpenMPCaptureRegions(
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
+ case OMPD_requires:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 44ee6b3b3a6..e74066ef43a 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -105,6 +105,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
case Decl::Import:
case Decl::OMPThreadPrivate:
case Decl::OMPCapturedExpr:
+ case Decl::OMPRequires:
case Decl::Empty:
// None of these decls require codegen support.
return;
@@ -2146,3 +2147,7 @@ void CodeGenModule::EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
return;
getOpenMPRuntime().emitUserDefinedReduction(CGF, D);
}
+
+void CodeGenModule::EmitOMPRequiresDecl(const OMPRequiresDecl *D) {
+ //Do nothing - here to avoid build errors
+}
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 01012cb3e91..d421729faa2 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -8273,6 +8273,7 @@ void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
case OMPD_declare_reduction:
case OMPD_taskloop:
case OMPD_taskloop_simd:
+ case OMPD_requires:
case OMPD_unknown:
llvm_unreachable("Unknown target directive for OpenMP device codegen.");
}
@@ -8748,6 +8749,7 @@ void CGOpenMPRuntime::emitTargetDataStandAloneCall(
case OMPD_target_parallel:
case OMPD_target_parallel_for:
case OMPD_target_parallel_for_simd:
+ case OMPD_requires:
case OMPD_unknown:
llvm_unreachable("Unexpected standalone target data directive.");
break;
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index 0553c18a772..45aafaa5c3c 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -762,6 +762,7 @@ static bool hasNestedSPMDDirective(ASTContext &Ctx,
case OMPD_declare_reduction:
case OMPD_taskloop:
case OMPD_taskloop_simd:
+ case OMPD_requires:
case OMPD_unknown:
llvm_unreachable("Unexpected directive.");
}
@@ -831,6 +832,7 @@ static bool supportsSPMDExecutionMode(ASTContext &Ctx,
case OMPD_declare_reduction:
case OMPD_taskloop:
case OMPD_taskloop_simd:
+ case OMPD_requires:
case OMPD_unknown:
break;
}
@@ -980,6 +982,7 @@ static bool hasNestedLightweightDirective(ASTContext &Ctx,
case OMPD_declare_reduction:
case OMPD_taskloop:
case OMPD_taskloop_simd:
+ case OMPD_requires:
case OMPD_unknown:
llvm_unreachable("Unexpected directive.");
}
@@ -1052,6 +1055,7 @@ static bool supportsLightweightRuntime(ASTContext &Ctx,
case OMPD_declare_reduction:
case OMPD_taskloop:
case OMPD_taskloop_simd:
+ case OMPD_requires:
case OMPD_unknown:
break;
}
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index bbb15353420..7305b0f3213 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -3903,6 +3903,7 @@ static void emitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_unified_address:
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
}
}
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index baafa98d5c8..cd30ad1a400 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4879,6 +4879,10 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
case Decl::OMPDeclareReduction:
EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(D));
break;
+
+ case Decl::OMPRequires:
+ EmitOMPRequiresDecl(cast<OMPRequiresDecl>(D));
+ break;
default:
// Make sure we handled everything we should, every other kind is a
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index ae7f7f3e191..baf3619ca88 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1224,6 +1224,10 @@ public:
void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
CodeGenFunction *CGF = nullptr);
+ /// Emit a code for requires directive.
+ /// \param D Requires declaration
+ void EmitOMPRequiresDecl(const OMPRequiresDecl *D);
+
/// Returns whether the given record has hidden LTO visibility and therefore
/// may participate in (single-module) CFI and whole-program vtable
/// optimization.
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index cdcbf797678..e8a17b5e12c 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -659,6 +659,10 @@ Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
/// annot_pragma_openmp_end
/// <function declaration/definition>
///
+/// requires directive:
+/// annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
+/// annot_pragma_openmp_end
+///
Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
DeclSpec::TST TagType, Decl *Tag) {
@@ -687,6 +691,46 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
}
break;
}
+ case OMPD_requires: {
+ SourceLocation StartLoc = ConsumeToken();
+ SmallVector<OMPClause *, 5> Clauses;
+ SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
+ FirstClauses(OMPC_unknown + 1);
+ if (Tok.is(tok::annot_pragma_openmp_end)) {
+ Diag(Tok, diag::err_omp_expected_clause)
+ << getOpenMPDirectiveName(OMPD_requires);
+ break;
+ }
+ while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ OpenMPClauseKind CKind = Tok.isAnnotation()
+ ? OMPC_unknown
+ : getOpenMPClauseKind(PP.getSpelling(Tok));
+ Actions.StartOpenMPClause(CKind);
+ OMPClause *Clause =
+ ParseOpenMPClause(OMPD_requires, CKind, !FirstClauses[CKind].getInt());
+ SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch);
+ FirstClauses[CKind].setInt(true);
+ if (Clause != nullptr)
+ Clauses.push_back(Clause);
+ if (Tok.is(tok::annot_pragma_openmp_end)) {
+ Actions.EndOpenMPClause();
+ break;
+ }
+ // Skip ',' if any.
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ Actions.EndOpenMPClause();
+ }
+ // Consume final annot_pragma_openmp_end
+ if (Clauses.size() == 0) {
+ Diag(Tok, diag::err_omp_expected_clause)
+ << getOpenMPDirectiveName(OMPD_requires);
+ ConsumeAnnotationToken();
+ return nullptr;
+ }
+ ConsumeAnnotationToken();
+ return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
+ }
case OMPD_declare_reduction:
ConsumeToken();
if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
@@ -1141,6 +1185,7 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
+ case OMPD_requires:
Diag(Tok, diag::err_omp_unexpected_directive)
<< 1 << getOpenMPDirectiveName(DKind);
SkipUntil(tok::annot_pragma_openmp_end);
@@ -1333,10 +1378,13 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_threads:
case OMPC_simd:
case OMPC_nogroup:
+ case OMPC_unified_address:
// OpenMP [2.7.1, Restrictions, p. 9]
// Only one ordered clause can appear on a loop directive.
// OpenMP [2.7.1, Restrictions, C/C++, p. 4]
// Only one nowait clause can appear on a for directive.
+ // OpenMP [5.0, Requires directive, Restrictions]
+ // Each of the requires clauses can appear at most once on the directive.
if (!FirstClause) {
Diag(Tok, diag::err_omp_more_one_clause)
<< getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 3767f40ecb2..bcf2c5c26ef 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -177,6 +177,9 @@ private:
Stack.back().first.empty();
}
+ /// Vector of previously declared requires directives
+ SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
+
public:
explicit DSAStackTy(Sema &S) : SemaRef(S) {}
@@ -351,7 +354,34 @@ public:
return OMPD_unknown;
return std::next(Stack.back().first.rbegin())->Directive;
}
-
+
+ /// Add requires decl to internal vector
+ void addRequiresDecl(OMPRequiresDecl *RD) {
+ RequiresDecls.push_back(RD);
+ }
+
+ /// Checks for a duplicate clause amongst previously declared requires
+ /// directives
+ bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
+ bool IsDuplicate = false;
+ for (OMPClause *CNew : ClauseList) {
+ for (const OMPRequiresDecl *D : RequiresDecls) {
+ for (const OMPClause *CPrev : D->clauselists()) {
+ if (CNew->getClauseKind() == CPrev->getClauseKind()) {
+ SemaRef.Diag(CNew->getBeginLoc(),
+ diag::err_omp_requires_clause_redeclaration)
+ << getOpenMPClauseName(CNew->getClauseKind());
+ SemaRef.Diag(CPrev->getBeginLoc(),
+ diag::note_omp_requires_previous_clause)
+ << getOpenMPClauseName(CPrev->getClauseKind());
+ IsDuplicate = true;
+ }
+ }
+ }
+ }
+ return IsDuplicate;
+ }
+
/// Set default data sharing attribute to none.
void setDefaultDSANone(SourceLocation Loc) {
assert(!isStackEmpty());
@@ -1899,6 +1929,30 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
return D;
}
+Sema::DeclGroupPtrTy
+Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
+ ArrayRef<OMPClause *> ClauseList) {
+ OMPRequiresDecl *D = nullptr;
+ if (!CurContext->isFileContext()) {
+ Diag(Loc, diag::err_omp_invalid_scope) << "requires";
+ } else {
+ D = CheckOMPRequiresDecl(Loc, ClauseList);
+ if (D) {
+ CurContext->addDecl(D);
+ DSAStack->addRequiresDecl(D);
+ }
+ }
+ return DeclGroupPtrTy::make(DeclGroupRef(D));
+}
+
+OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
+ ArrayRef<OMPClause *> ClauseList) {
+ if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
+ return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
+ ClauseList);
+ return nullptr;
+}
+
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
const ValueDecl *D,
const DSAStackTy::DSAVarData &DVar,
@@ -2544,6 +2598,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_end_declare_target:
+ case OMPD_requires:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -3385,6 +3440,7 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
case OMPD_threadprivate:
case OMPD_declare_reduction:
case OMPD_declare_simd:
+ case OMPD_requires:
llvm_unreachable("OpenMP Directive is not allowed");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -7954,6 +8010,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_unified_address:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -8039,6 +8096,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_distribute_simd:
case OMPD_teams_distribute:
case OMPD_teams_distribute_simd:
+ case OMPD_requires:
llvm_unreachable("Unexpected OpenMP directive with if-clause");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -8104,6 +8162,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_distribute_simd:
case OMPD_teams_distribute:
case OMPD_teams_distribute_simd:
+ case OMPD_requires:
llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -8167,6 +8226,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_ordered:
case OMPD_atomic:
case OMPD_distribute_simd:
+ case OMPD_requires:
llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -8230,6 +8290,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_ordered:
case OMPD_atomic:
case OMPD_distribute_simd:
+ case OMPD_requires:
llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -8293,6 +8354,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_atomic:
case OMPD_distribute_simd:
case OMPD_target_teams:
+ case OMPD_requires:
llvm_unreachable("Unexpected OpenMP directive with schedule clause");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -8356,6 +8418,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_ordered:
case OMPD_atomic:
case OMPD_target_teams:
+ case OMPD_requires:
llvm_unreachable("Unexpected OpenMP directive with schedule clause");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -8419,6 +8482,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPD_ordered:
case OMPD_atomic:
case OMPD_distribute_simd:
+ case OMPD_requires:
llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
case OMPD_unknown:
llvm_unreachable("Unknown OpenMP directive");
@@ -8468,6 +8532,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_unified_address:
llvm_unreachable("Unexpected OpenMP clause.");
}
return CaptureRegion;
@@ -8785,6 +8850,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_unified_address:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -8941,6 +9007,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
case OMPC_from:
case OMPC_use_device_ptr:
case OMPC_is_device_ptr:
+ case OMPC_unified_address:
llvm_unreachable("Clause is not allowed.");
}
return Res;
@@ -9096,6 +9163,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_nogroup:
Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
break;
+ case OMPC_unified_address:
+ Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
@@ -9196,6 +9266,11 @@ OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
return new (Context) OMPNogroupClause(StartLoc, EndLoc);
}
+OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
+}
+
OMPClause *Sema::ActOnOpenMPVarListClause(
OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
@@ -9303,6 +9378,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
case OMPC_defaultmap:
case OMPC_unknown:
case OMPC_uniform:
+ case OMPC_unified_address:
llvm_unreachable("Clause is not allowed.");
}
return Res;
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 340e0c67172..5f2b05c0893 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2736,6 +2736,11 @@ Decl *TemplateDeclInstantiator::VisitOMPThreadPrivateDecl(
return TD;
}
+Decl *TemplateDeclInstantiator::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
+ llvm_unreachable(
+ "Requires directive cannot be instantiated within a dependent context");
+}
+
Decl *TemplateDeclInstantiator::VisitOMPDeclareReductionDecl(
OMPDeclareReductionDecl *D) {
// Instantiate type and check if it is allowed.
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index f8f6304085a..2bee5e7ec82 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -8414,6 +8414,12 @@ TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
}
template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
+ OMPUnifiedAddressClause *C) {
+ llvm_unreachable("unified address clause cannot appear in dependent context");
+}
+
+template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
llvm::SmallVector<Expr *, 16> Vars;
diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp
index da482717f45..0be9a3bfd6e 100644
--- a/clang/lib/Serialization/ASTCommon.cpp
+++ b/clang/lib/Serialization/ASTCommon.cpp
@@ -383,6 +383,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) {
case Decl::ClassScopeFunctionSpecialization:
case Decl::Import:
case Decl::OMPThreadPrivate:
+ case Decl::OMPRequires:
case Decl::OMPCapturedExpr:
case Decl::OMPDeclareReduction:
case Decl::BuiltinTemplate:
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index c143cb03689..2e0d424b137 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -11721,6 +11721,9 @@ OMPClause *OMPClauseReader::readClause() {
case OMPC_nogroup:
C = new (Context) OMPNogroupClause();
break;
+ case OMPC_unified_address:
+ C = new (Context) OMPUnifiedAddressClause();
+ break;
case OMPC_private:
C = OMPPrivateClause::CreateEmpty(Context, Record.readInt());
break;
@@ -11949,6 +11952,8 @@ void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {}
void OMPClauseReader::VisitOMPNogroupClause(OMPNogroupClause *) {}
+void OMPClauseReader::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {}
+
void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {
C->setLParenLoc(Record.readSourceLocation());
unsigned NumVars = C->varlist_size();
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index d06a6226af7..fc9e7e82aef 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -30,6 +30,7 @@
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/LambdaCapture.h"
#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/OpenMPClause.h"
#include "clang/AST/Redeclarable.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/TemplateBase.h"
@@ -446,6 +447,7 @@ namespace clang {
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
+ void VisitOMPRequiresDecl(OMPRequiresDecl *D);
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
};
@@ -2630,6 +2632,17 @@ void ASTDeclReader::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
D->setVars(Vars);
}
+void ASTDeclReader::VisitOMPRequiresDecl(OMPRequiresDecl * D) {
+ VisitDecl(D);
+ unsigned NumClauses = D->clauselist_size();
+ SmallVector<OMPClause *, 8> Clauses;
+ Clauses.reserve(NumClauses);
+ OMPClauseReader ClauseReader(Record);
+ for (unsigned I = 0; I != NumClauses; ++I)
+ Clauses.push_back(ClauseReader.readClause());
+ D->setClauses(Clauses);
+}
+
void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
VisitValueDecl(D);
D->setLocation(ReadSourceLocation());
@@ -3830,6 +3843,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
case DECL_OMP_THREADPRIVATE:
D = OMPThreadPrivateDecl::CreateDeserialized(Context, ID, Record.readInt());
break;
+ case DECL_OMP_REQUIRES:
+ D = OMPRequiresDecl::CreateDeserialized(Context, ID, Record.readInt());
+ break;
case DECL_OMP_DECLARE_REDUCTION:
D = OMPDeclareReductionDecl::CreateDeserialized(Context, ID);
break;
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 689aa8ff96d..db4ab455bbf 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -6932,3 +6932,5 @@ void OMPClauseWriter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
Record.AddDeclRef(M.getAssociatedDeclaration());
}
}
+
+void OMPClauseWriter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {}
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index d757f609ea2..e120f14b81e 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/OpenMPClause.h"
#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Serialization/ASTReader.h"
@@ -144,6 +145,7 @@ namespace clang {
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
+ void VisitOMPRequiresDecl(OMPRequiresDecl *D);
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
@@ -1739,6 +1741,15 @@ void ASTDeclWriter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
Code = serialization::DECL_OMP_THREADPRIVATE;
}
+void ASTDeclWriter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
+ Record.push_back(D->clauselist_size());
+ VisitDecl(D);
+ OMPClauseWriter ClauseWriter(Record);
+ for (OMPClause *C : D->clauselists())
+ ClauseWriter.writeClause(C);
+ Code = serialization::DECL_OMP_REQUIRES;
+}
+
void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
VisitValueDecl(D);
Record.AddSourceLocation(D->getBeginLoc());
diff --git a/clang/test/OpenMP/requires_unified_address_ast_print.cpp b/clang/test/OpenMP/requires_unified_address_ast_print.cpp
new file mode 100644
index 00000000000..641d6c4b90b
--- /dev/null
+++ b/clang/test/OpenMP/requires_unified_address_ast_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 unified_address
+// CHECK:#pragma omp requires unified_address
+
+#endif
diff --git a/clang/test/OpenMP/requires_unified_address_messages.cpp b/clang/test/OpenMP/requires_unified_address_messages.cpp
new file mode 100644
index 00000000000..ed5d27a5ec9
--- /dev/null
+++ b/clang/test/OpenMP/requires_unified_address_messages.cpp
@@ -0,0 +1,36 @@
+// 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}}
+
+#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 // 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}}
+
+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 <typename T> 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'}}
+}
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 6d2cf888f38..6bd9d738738 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2207,6 +2207,9 @@ void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
+void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
+ const OMPUnifiedAddressClause *) {}
+
void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
Visitor->AddStmt(C->getDevice());
}
@@ -6220,6 +6223,7 @@ CXCursor clang_getCursorDefinition(CXCursor C) {
case Decl::Import:
case Decl::OMPThreadPrivate:
case Decl::OMPDeclareReduction:
+ case Decl::OMPRequires:
case Decl::ObjCTypeParam:
case Decl::BuiltinTemplate:
case Decl::PragmaComment:
OpenPOWER on IntegriCloud