jyu2 updated this revision to Diff 475013.
jyu2 added a comment.
try fix format again
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D137851/new/
https://reviews.llvm.org/D137851
Files:
clang/include/clang/AST/OpenMPClause.h
clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/include/clang/Basic/OpenMPKinds.def
clang/include/clang/Basic/OpenMPKinds.h
clang/include/clang/Parse/Parser.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/OpenMPClause.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/Basic/OpenMPKinds.cpp
clang/lib/CodeGen/CGStmtOpenMP.cpp
clang/lib/Parse/ParseOpenMP.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/test/OpenMP/error_ast_print.cpp
clang/test/OpenMP/error_message.cpp
clang/tools/libclang/CIndex.cpp
flang/lib/Semantics/check-omp-structure.cpp
llvm/include/llvm/Frontend/OpenMP/OMP.td
Index: llvm/include/llvm/Frontend/OpenMP/OMP.td
===================================================================
--- llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -301,6 +301,9 @@
let clangClass = "OMPAtomicDefaultMemOrderClause";
let flangClass = "OmpAtomicDefaultMemOrderClause";
}
+def OMPC_At : Clause<"at"> {
+ let clangClass = "OMPAtClause";
+}
def OMPC_Allocate : Clause<"allocate"> {
let clangClass = "OMPAllocateClause";
let flangClass = "OmpAllocateClause";
@@ -527,7 +530,11 @@
}
def OMP_TaskYield : Directive<"taskyield"> {}
def OMP_Barrier : Directive<"barrier"> {}
-def OMP_Error : Directive<"error"> {}
+def OMP_Error : Directive<"error"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_At>
+ ];
+}
def OMP_TaskWait : Directive<"taskwait"> {
let allowedClauses = [
VersionedClause<OMPC_Depend, 50>
Index: flang/lib/Semantics/check-omp-structure.cpp
===================================================================
--- flang/lib/Semantics/check-omp-structure.cpp
+++ flang/lib/Semantics/check-omp-structure.cpp
@@ -1868,6 +1868,7 @@
CHECK_SIMPLE_CLAUSE(Use, OMPC_use)
CHECK_SIMPLE_CLAUSE(Novariants, OMPC_novariants)
CHECK_SIMPLE_CLAUSE(Nocontext, OMPC_nocontext)
+CHECK_SIMPLE_CLAUSE(At, OMPC_at)
CHECK_SIMPLE_CLAUSE(Filter, OMPC_filter)
CHECK_SIMPLE_CLAUSE(When, OMPC_when)
CHECK_SIMPLE_CLAUSE(AdjustArgs, OMPC_adjust_args)
Index: clang/tools/libclang/CIndex.cpp
===================================================================
--- clang/tools/libclang/CIndex.cpp
+++ clang/tools/libclang/CIndex.cpp
@@ -2443,6 +2443,8 @@
void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
const OMPAtomicDefaultMemOrderClause *) {}
+void OMPClauseEnqueue::VisitOMPAtClause(const OMPAtClause *) {}
+
void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
Visitor->AddStmt(C->getDevice());
}
Index: clang/test/OpenMP/error_message.cpp
===================================================================
--- clang/test/OpenMP/error_message.cpp
+++ clang/test/OpenMP/error_message.cpp
@@ -7,19 +7,19 @@
if (argc)
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
if (argc) {
-#pragma omp error
+#pragma omp error // expected-error {{ERROR}}
}
while (argc)
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
while (argc) {
-#pragma omp error
+#pragma omp error // expected-error {{ERROR}}
}
do
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
while (argc)
;
do {
-#pragma omp error
+#pragma omp error // expected-error {{ERROR}}
} while (argc);
switch (argc)
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
@@ -28,47 +28,75 @@
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
switch (argc)
case 1: {
-#pragma omp error
+#pragma omp error // expected-error {{ERROR}}
}
switch (argc) {
-#pragma omp error
+#pragma omp error // expected-error {{ERROR}}
case 1:
-#pragma omp error
+#pragma omp error // expected-error {{ERROR}}
break;
default: {
-#pragma omp error
+#pragma omp error // expected-error {{ERROR}}
} break;
}
for (;;)
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
for (;;) {
-#pragma omp error
+#pragma omp error // expected-error {{ERROR}}
}
label:
-#pragma omp error
+#pragma omp error // expected-error {{ERROR}}
label1 : {
-#pragma omp error
+#pragma omp error // expected-error {{ERROR}}
}
if (1)
label2:
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
+// expected-error@+1 {{ERROR}}
+#pragma omp error at() // expected-error {{expected 'compilation' or 'execution' in OpenMP clause 'at'}}
+
+// expected-error@+1 {{ERROR}}
+#pragma omp error at(up) // expected-error {{expected 'compilation' or 'execution' in OpenMP clause 'at'}}
+
+// expected-error@+3 {{ERROR}}
+// expected-error@+2 {{expected ')'}}
+// expected-note@+1 {{to match this '('}}
+#pragma omp error at(up(a)) // expected-error {{expected 'compilation' or 'execution' in OpenMP clause 'at'}}
+
+#pragma omp error at(execution) // no error
+
+#pragma omp error at(compilation) // expected-error {{ERROR}}
return T();
}
+#pragma omp error at(execution) // expected-error {{unexpected 'execution' modifier in non-executable context}}
+
+#pragma omp error at(compilation) // expected-error {{ERROR}}
+class A {
+
+#pragma omp error at(compilation) // expected-error {{ERROR}}
+
+#pragma omp error at(execution) // expected-error {{unexpected 'execution' modifier in non-executable context}}
+ int A;
+};
+
int main(int argc, char **argv) {
+// expected-error@+1 {{ERROR}}
#pragma omp error
;
+// expected-error@+1 {{ERROR}}
#pragma omp error untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp error'}}
-#pragma omp error unknown // expected-warning {{extra tokens at the end of '#pragma omp error' are ignored}}
if (argc)
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
if (argc) {
+// expected-error@+1 {{ERROR}}
#pragma omp error
}
while (argc)
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
while (argc) {
+// expected-error@+1 {{ERROR}}
#pragma omp error
}
do
@@ -76,6 +104,7 @@
while (argc)
;
do {
+// expected-error@+1 {{ERROR}}
#pragma omp error
} while (argc);
switch (argc)
@@ -85,25 +114,32 @@
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
switch (argc)
case 1: {
+// expected-error@+1 {{ERROR}}
#pragma omp error
}
switch (argc) {
+// expected-error@+1 {{ERROR}}
#pragma omp error
case 1:
+// expected-error@+1 {{ERROR}}
#pragma omp error
break;
default: {
+// expected-error@+1 {{ERROR}}
#pragma omp error
} break;
}
for (;;)
#pragma omp error // expected-error {{'#pragma omp error' cannot be an immediate substatement}}
for (;;) {
+// expected-error@+1 {{ERROR}}
#pragma omp error
}
label:
+// expected-error@+1 {{ERROR}}
#pragma omp error
label1 : {
+// expected-error@+1 {{ERROR}}
#pragma omp error
}
if (1)
Index: clang/test/OpenMP/error_ast_print.cpp
===================================================================
--- clang/test/OpenMP/error_ast_print.cpp
+++ clang/test/OpenMP/error_ast_print.cpp
@@ -13,16 +13,16 @@
void foo() {}
// CHECK: template <typename T, int N> int tmain(T argc, char **argv)
// CHECK: static int a;
-// CHECK-NEXT: #pragma omp error
+// CHECK-NEXT: #pragma omp error at(execution)
// CHECK-NEXT: a = argv[0][0];
// CHECK-NEXT: ++a;
-// CHECK-NEXT: #pragma omp error
+// CHECK-NEXT: #pragma omp error at(execution)
// CHECK-NEXT: {
// CHECK-NEXT: int b = 10;
// CHECK-NEXT: T c = 100;
// CHECK-NEXT: a = b + c;
// CHECK-NEXT: }
-// CHECK-NEXT: #pragma omp error
+// CHECK-NEXT: #pragma omp error at(execution)
// CHECK-NEXT: foo();
// CHECK-NEXT: return N;
@@ -30,16 +30,16 @@
int tmain(T argc, char **argv) {
T b = argc, c, d, e, f, g;
static int a;
-#pragma omp error
+#pragma omp error at(execution)
a = argv[0][0];
++a;
-#pragma omp error
+#pragma omp error at(execution)
{
int b = 10;
T c = 100;
a = b + c;
}
-#pragma omp error
+#pragma omp error at(execution)
foo();
return N;
}
@@ -47,16 +47,16 @@
// CHECK: int main(int argc, char **argv)
// CHECK-NEXT: int b = argc, c, d, e, f, g;
// CHECK-NEXT: static int a;
-// CHECK-NEXT: #pragma omp error
+// CHECK-NEXT: #pragma omp error at(execution)
// CHECK-NEXT: a = 2;
-// CHECK-NEXT: #pragma omp error
+// CHECK-NEXT: #pragma omp error at(execution)
// CHECK-NEXT: foo();
int main (int argc, char **argv) {
int b = argc, c, d, e, f, g;
static int a;
-#pragma omp error
+#pragma omp error at(execution)
a=2;
-#pragma omp error
+#pragma omp error at(execution)
foo();
}
#endif
Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -6982,6 +6982,12 @@
Record.AddSourceLocation(C->getAtomicDefaultMemOrderKindKwLoc());
}
+void OMPClauseWriter::VisitOMPAtClause(OMPAtClause *C) {
+ Record.push_back(C->getAtKind());
+ Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddSourceLocation(C->getAtKindKwLoc());
+}
+
void OMPClauseWriter::VisitOMPNontemporalClause(OMPNontemporalClause *C) {
Record.push_back(C->varlist_size());
Record.AddSourceLocation(C->getLParenLoc());
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -9934,7 +9934,10 @@
case llvm::omp::OMPC_atomic_default_mem_order:
C = new (Context) OMPAtomicDefaultMemOrderClause();
break;
- case llvm::omp::OMPC_private:
+ case llvm::omp::OMPC_at:
+ C = new (Context) OMPAtClause();
+ break;
+ case llvm::omp::OMPC_private:
C = OMPPrivateClause::CreateEmpty(Context, Record.readInt());
break;
case llvm::omp::OMPC_firstprivate:
@@ -10336,6 +10339,12 @@
C->setAtomicDefaultMemOrderKindKwLoc(Record.readSourceLocation());
}
+void OMPClauseReader::VisitOMPAtClause(OMPAtClause *C) {
+ C->setAtKind(static_cast<OpenMPAtClauseKind>(Record.readInt()));
+ C->setLParenLoc(Record.readSourceLocation());
+ C->setAtKindKwLoc(Record.readSourceLocation());
+}
+
void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {
C->setLParenLoc(Record.readSourceLocation());
unsigned NumVars = C->varlist_size();
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -2351,6 +2351,17 @@
return getSema().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
}
+ /// Build a new OpenMP 'at' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc, LParenLoc,
+ EndLoc);
+ }
/// Rebuild the operand to an Objective-C \@synchronized statement.
///
/// By default, performs semantic analysis to build the new statement.
@@ -9855,6 +9866,13 @@
"atomic_default_mem_order clause cannot appear in dependent context");
}
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
+ return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
+ C->getBeginLoc(), C->getLParenLoc(),
+ C->getEndLoc());
+}
+
template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
Index: clang/lib/Sema/SemaOpenMP.cpp
===================================================================
--- clang/lib/Sema/SemaOpenMP.cpp
+++ clang/lib/Sema/SemaOpenMP.cpp
@@ -6308,7 +6308,7 @@
break;
case OMPD_error:
assert(AStmt == nullptr &&
- "No associated statement allowed for 'omp taskyield' directive");
+ "No associated statement allowed for 'omp error' directive");
Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc);
break;
case OMPD_barrier:
@@ -6719,6 +6719,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_when:
+ case OMPC_at:
default:
llvm_unreachable("Unexpected clause");
}
@@ -11029,6 +11030,15 @@
StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
SourceLocation StartLoc,
SourceLocation EndLoc) {
+ const OMPAtClause *AtC = nullptr;
+ for (auto *AC :
+ OMPExecutableDirective::getClausesOfKind<OMPAtClause>(Clauses))
+ AtC = AC;
+ if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) {
+ Diag(AtC ? AtC->getBeginLoc() : StartLoc, diag::err_diagnose_if_succeeded)
+ << "ERROR";
+ return StmtError();
+ }
return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses);
}
@@ -15171,6 +15181,7 @@
case OMPC_match:
case OMPC_nontemporal:
case OMPC_order:
+ case OMPC_at:
case OMPC_destroy:
case OMPC_inclusive:
case OMPC_exclusive:
@@ -16096,6 +16107,7 @@
case OMPC_match:
case OMPC_nontemporal:
case OMPC_order:
+ case OMPC_at:
case OMPC_destroy:
case OMPC_detach:
case OMPC_inclusive:
@@ -16498,6 +16510,10 @@
Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
ArgumentLoc, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_at:
+ Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument),
+ ArgumentLoc, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_final:
case OMPC_num_threads:
@@ -16676,6 +16692,22 @@
LParenLoc, EndLoc);
}
+OMPClause *Sema::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
+ SourceLocation KindKwLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ if (Kind == OMPC_AT_unknown) {
+ Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
+ << getListOfPossibleValues(OMPC_at, /*First=*/0,
+ /*Last=*/OMPC_AT_unknown)
+ << getOpenMPClauseName(OMPC_at);
+ return nullptr;
+ }
+ return new (Context)
+ OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
+}
+
OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
SourceLocation KindKwLoc,
SourceLocation StartLoc,
@@ -16875,6 +16907,7 @@
case OMPC_match:
case OMPC_nontemporal:
case OMPC_order:
+ case OMPC_at:
case OMPC_destroy:
case OMPC_novariants:
case OMPC_nocontext:
@@ -17131,6 +17164,7 @@
case OMPC_match:
case OMPC_nontemporal:
case OMPC_order:
+ case OMPC_at:
case OMPC_novariants:
case OMPC_nocontext:
case OMPC_detach:
@@ -17685,6 +17719,7 @@
case OMPC_device_type:
case OMPC_match:
case OMPC_order:
+ case OMPC_at:
case OMPC_destroy:
case OMPC_novariants:
case OMPC_nocontext:
Index: clang/lib/Parse/ParseOpenMP.cpp
===================================================================
--- clang/lib/Parse/ParseOpenMP.cpp
+++ clang/lib/Parse/ParseOpenMP.cpp
@@ -1627,6 +1627,45 @@
return false;
}
+/// <clause> [clause[ [,] clause] ... ]
+///
+/// clauses: for error directive
+/// 'at' '(' compilation | execution ')'
+/// 'severity' '(' fatal | warning ')'
+/// 'message' '(' msg-string ')'
+/// ....
+void Parser::ParseOpenMPClauses(OpenMPDirectiveKind DKind,
+ SmallVector<clang::OMPClause *, 1> *Clauses,
+ SourceLocation Loc) {
+ SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
+ llvm::omp::Clause_enumSize + 1>
+ FirstClauses(llvm::omp::Clause_enumSize + 1);
+ while (Tok.isNot(tok::annot_pragma_openmp_end)) {
+ OpenMPClauseKind CKind = Tok.isAnnotation()
+ ? OMPC_unknown
+ : getOpenMPClauseKind(PP.getSpelling(Tok));
+ Actions.StartOpenMPClause(CKind);
+ OMPClause *Clause = ParseOpenMPClause(
+ DKind, CKind, !FirstClauses[unsigned(CKind)].getInt());
+ SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
+ StopBeforeMatch);
+ FirstClauses[unsigned(CKind)].setInt(true);
+ if (Clause != nullptr)
+ Clauses->push_back(Clause);
+ OMPAtClause *AtC = CKind == OMPC_at ? cast<OMPAtClause>(Clause) : nullptr;
+ if (CKind == OMPC_at && AtC->getAtKind() == OMPC_AT_execution)
+ Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier);
+ if (Tok.is(tok::annot_pragma_openmp_end)) {
+ Actions.EndOpenMPClause();
+ break;
+ }
+ // Skip ',' if any.
+ if (Tok.is(tok::comma))
+ ConsumeToken();
+ Actions.EndOpenMPClause();
+ }
+}
+
/// `omp assumes` or `omp begin/end assumes` <clause> [[,]<clause>]...
/// where
///
@@ -2124,6 +2163,13 @@
ConsumeAnnotationToken();
return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
}
+ case OMPD_error: {
+ SmallVector<OMPClause *, 1> Clauses;
+ SourceLocation StartLoc = ConsumeToken();
+ ParseOpenMPClauses(DKind, &Clauses, StartLoc);
+ Actions.ActOnOpenMPErrorDirective(Clauses, StartLoc, SourceLocation());
+ break;
+ }
case OMPD_assumes:
case OMPD_begin_assumes:
ParseOpenMPAssumesDirective(DKind, ConsumeToken());
@@ -2310,7 +2356,6 @@
case OMPD_unroll:
case OMPD_task:
case OMPD_taskyield:
- case OMPD_error:
case OMPD_barrier:
case OMPD_taskwait:
case OMPD_taskgroup:
@@ -2711,6 +2756,10 @@
ParsedStmtContext()) {
Diag(Tok, diag::err_omp_immediate_directive)
<< getOpenMPDirectiveName(DKind) << 0;
+ if (DKind == OMPD_error) {
+ SkipUntil(tok::annot_pragma_openmp_end);
+ break;
+ }
}
HasAssociatedStatement = false;
// Fall through for further analysis.
@@ -3170,6 +3219,7 @@
case OMPC_default:
case OMPC_proc_bind:
case OMPC_atomic_default_mem_order:
+ case OMPC_at:
case OMPC_order:
case OMPC_bind:
// OpenMP [2.14.3.1, Restrictions]
@@ -3180,6 +3230,8 @@
// OpenMP [5.0, Requires directive, Restrictions]
// At most one atomic_default_mem_order clause can appear
// on the directive
+ // OpenMP [5.1, Requires directive, Restrictions]
+ // At most one at clause can appear on the directive
// OpenMP 5.1, 2.11.7 loop Construct, Restrictions.
// At most one bind clause can appear on a loop directive.
if (!FirstClause && CKind != OMPC_order) {
Index: clang/lib/CodeGen/CGStmtOpenMP.cpp
===================================================================
--- clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -6512,6 +6512,7 @@
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
case OMPC_atomic_default_mem_order:
+ case OMPC_at:
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
Index: clang/lib/Basic/OpenMPKinds.cpp
===================================================================
--- clang/lib/Basic/OpenMPKinds.cpp
+++ clang/lib/Basic/OpenMPKinds.cpp
@@ -104,6 +104,11 @@
#define OPENMP_DEVICE_TYPE_KIND(Name) .Case(#Name, OMPC_DEVICE_TYPE_##Name)
#include "clang/Basic/OpenMPKinds.def"
.Default(OMPC_DEVICE_TYPE_unknown);
+ case OMPC_at:
+ return llvm::StringSwitch<OpenMPAtClauseKind>(Str)
+#define OPENMP_AT_KIND(Name) .Case(#Name, OMPC_AT_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_AT_unknown);
case OMPC_lastprivate:
return llvm::StringSwitch<OpenMPLastprivateModifier>(Str)
#define OPENMP_LASTPRIVATE_KIND(Name) .Case(#Name, OMPC_LASTPRIVATE_##Name)
@@ -336,6 +341,17 @@
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'device_type' clause type");
+ case OMPC_at:
+ switch (Type) {
+ case OMPC_AT_unknown:
+ return "unknown";
+#define OPENMP_AT_KIND(Name) \
+ case OMPC_AT_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'at' clause type");
+ llvm_unreachable("Invalid OpenMP 'at' clause type");
case OMPC_lastprivate:
switch (Type) {
case OMPC_LASTPRIVATE_unknown:
Index: clang/lib/AST/StmtProfile.cpp
===================================================================
--- clang/lib/AST/StmtProfile.cpp
+++ clang/lib/AST/StmtProfile.cpp
@@ -530,6 +530,8 @@
void OMPClauseProfiler::VisitOMPAtomicDefaultMemOrderClause(
const OMPAtomicDefaultMemOrderClause *C) {}
+void OMPClauseProfiler::VisitOMPAtClause(const OMPAtClause *C) {}
+
void OMPClauseProfiler::VisitOMPScheduleClause(const OMPScheduleClause *C) {
VistOMPClauseWithPreInit(C);
if (auto *S = C->getChunkSize())
Index: clang/lib/AST/OpenMPClause.cpp
===================================================================
--- clang/lib/AST/OpenMPClause.cpp
+++ clang/lib/AST/OpenMPClause.cpp
@@ -152,6 +152,7 @@
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
case OMPC_atomic_default_mem_order:
+ case OMPC_at:
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
@@ -251,6 +252,7 @@
case OMPC_reverse_offload:
case OMPC_dynamic_allocators:
case OMPC_atomic_default_mem_order:
+ case OMPC_at:
case OMPC_device_type:
case OMPC_match:
case OMPC_nontemporal:
@@ -1781,6 +1783,11 @@
<< ")";
}
+void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {
+ OS << "at(" << getOpenMPSimpleClauseTypeName(OMPC_at, Node->getAtKind())
+ << ")";
+}
+
void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
OS << "schedule(";
if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -11826,6 +11826,13 @@
OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc,
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc);
+ /// Called on well-formed 'at' clause.
+ OMPClause *ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
+ SourceLocation KindLoc,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc);
+
/// Data used for processing a list of variables in OpenMP clauses.
struct OpenMPVarListDataTy final {
Expr *DepModOrTailExpr = nullptr;
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -3293,6 +3293,15 @@
/// Parse 'omp end assumes' directive.
void ParseOpenMPEndAssumesDirective(SourceLocation Loc);
+ /// Parses clauses for directive.
+ ///
+ /// \param DKind Kind of current directive.
+ /// \param clauses for current directive.
+ /// \param start location for clauses of current directive
+ void ParseOpenMPClauses(OpenMPDirectiveKind DKind,
+ SmallVector<clang::OMPClause *, 1> *Clauses,
+ SourceLocation Loc);
+
/// Parse clauses for '#pragma omp [begin] declare target'.
void ParseOMPDeclareTargetClauses(Sema::DeclareTargetContextInfo &DTCI);
Index: clang/include/clang/Basic/OpenMPKinds.h
===================================================================
--- clang/include/clang/Basic/OpenMPKinds.h
+++ clang/include/clang/Basic/OpenMPKinds.h
@@ -131,6 +131,13 @@
OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
};
+/// OpenMP attributes for 'at' clause.
+enum OpenMPAtClauseKind {
+#define OPENMP_AT_KIND(Name) OMPC_AT_##Name,
+#include "clang/Basic/OpenMPKinds.def"
+ OMPC_AT_unknown
+};
+
/// OpenMP device type for 'device_type' clause.
enum OpenMPDeviceType {
#define OPENMP_DEVICE_TYPE_KIND(Name) \
Index: clang/include/clang/Basic/OpenMPKinds.def
===================================================================
--- clang/include/clang/Basic/OpenMPKinds.def
+++ clang/include/clang/Basic/OpenMPKinds.def
@@ -41,6 +41,9 @@
#ifndef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND
#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name)
#endif
+#ifndef OPENMP_AT_KIND
+#define OPENMP_AT_KIND(Name)
+#endif
#ifndef OPENMP_DEFAULTMAP_MODIFIER
#define OPENMP_DEFAULTMAP_MODIFIER(Name)
#endif
@@ -119,6 +122,10 @@
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel)
OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(relaxed)
+// Modifiers for 'at' clause.
+OPENMP_AT_KIND(compilation)
+OPENMP_AT_KIND(execution)
+
// Map types for 'map' clause.
OPENMP_MAP_KIND(alloc)
OPENMP_MAP_KIND(to)
@@ -179,6 +186,7 @@
#undef OPENMP_SCHEDULE_MODIFIER
#undef OPENMP_SCHEDULE_KIND
#undef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND
+#undef OPENMP_AT_KIND
#undef OPENMP_MAP_KIND
#undef OPENMP_MAP_MODIFIER_KIND
#undef OPENMP_MOTION_MODIFIER_KIND
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1401,6 +1401,8 @@
"expected declarator on 'omp declare mapper' directive">;
def err_omp_unexpected_append_op : Error<
"unexpected operation specified in 'append_args' clause, expected 'interop'">;
+def err_omp_unexpected_execution_modifier : Error<
+ "unexpected 'execution' modifier in non-executable context">;
def err_omp_declare_variant_wrong_clause : Error<
"expected %select{'match'|'match', 'adjust_args', or 'append_args'}0 clause "
"on 'omp declare variant' directive">;
Index: clang/include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- clang/include/clang/AST/RecursiveASTVisitor.h
+++ clang/include/clang/AST/RecursiveASTVisitor.h
@@ -3310,6 +3310,11 @@
return true;
}
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAtClause(OMPAtClause *) {
+ return true;
+}
+
template <typename Derived>
bool
RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
Index: clang/include/clang/AST/OpenMPClause.h
===================================================================
--- clang/include/clang/AST/OpenMPClause.h
+++ clang/include/clang/AST/OpenMPClause.h
@@ -1563,6 +1563,85 @@
}
};
+/// This represents 'at' clause in the '#pragma omp error' directive
+///
+/// \code
+/// #pragma omp error at(compilation)
+/// \endcode
+/// In this example directive '#pragma omp error' has simple
+/// 'at' clause with kind 'complilation'.
+class OMPAtClause final : public OMPClause {
+ friend class OMPClauseReader;
+
+ /// Location of '('
+ SourceLocation LParenLoc;
+
+ /// A kind of the 'at' clause.
+ OpenMPAtClauseKind Kind = OMPC_AT_unknown;
+
+ /// Start location of the kind in source code.
+ SourceLocation KindKwLoc;
+
+ /// Set kind of the clause.
+ ///
+ /// \param K Kind of clause.
+ void setAtKind(OpenMPAtClauseKind K) { Kind = K; }
+
+ /// Set clause kind location.
+ ///
+ /// \param KLoc Kind location.
+ void setAtKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+ /// Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+public:
+ /// Build 'at' clause with argument \a A ('compilation' or 'execution').
+ ///
+ /// \param A Argument of the clause ('compilation' or 'execution').
+ /// \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.
+ OMPAtClause(OpenMPAtClauseKind A, SourceLocation ALoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(llvm::omp::OMPC_at, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Kind(A), KindKwLoc(ALoc) {}
+
+ /// Build an empty clause.
+ OMPAtClause()
+ : OMPClause(llvm::omp::OMPC_at, SourceLocation(), SourceLocation()) {}
+
+ /// Returns the locaiton of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// Returns kind of the clause.
+ OpenMPAtClauseKind getAtKind() const { return Kind; }
+
+ /// Returns location of clause kind.
+ SourceLocation getAtKindKwLoc() const { return KindKwLoc; }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ const_child_range children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ child_range used_children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+ const_child_range used_children() const {
+ return const_child_range(const_child_iterator(), const_child_iterator());
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == llvm::omp::OMPC_at;
+ }
+};
+
/// This represents 'schedule' clause in the '#pragma omp ...' directive.
///
/// \code
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits