[clang] 4bbdb01 - [OpenACC] Implement 'init' and 'shutdown' constructs
via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 19 12:21:57 PST 2024
Author: erichkeane
Date: 2024-12-19T12:21:50-08:00
New Revision: 4bbdb018a6cb564783cfb9c65ca82b81c6006bb6
URL: https://github.com/llvm/llvm-project/commit/4bbdb018a6cb564783cfb9c65ca82b81c6006bb6
DIFF: https://github.com/llvm/llvm-project/commit/4bbdb018a6cb564783cfb9c65ca82b81c6006bb6.diff
LOG: [OpenACC] Implement 'init' and 'shutdown' constructs
These two constructs are very simple and similar, and only support 3
different clauses, two of which are already implemented. This patch
adds AST nodes for both constructs, and leaves the device_num clause
unimplemented, but enables the other two.
Added:
clang/test/AST/ast-print-openacc-init-construct.cpp
clang/test/AST/ast-print-openacc-shutdown-construct.cpp
clang/test/SemaOpenACC/init-construct-ast.cpp
clang/test/SemaOpenACC/init-construct.cpp
clang/test/SemaOpenACC/shutdown-construct-ast.cpp
clang/test/SemaOpenACC/shutdown-construct.cpp
Modified:
clang/include/clang-c/Index.h
clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/AST/StmtOpenACC.h
clang/include/clang/AST/TextNodeDumper.h
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Basic/StmtNodes.td
clang/include/clang/Serialization/ASTBitCodes.h
clang/lib/AST/StmtOpenACC.cpp
clang/lib/AST/StmtPrinter.cpp
clang/lib/AST/StmtProfile.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/CodeGen/CGStmt.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/lib/Parse/ParseOpenACC.cpp
clang/lib/Sema/SemaExceptionSpec.cpp
clang/lib/Sema/SemaOpenACC.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
clang/test/ParserOpenACC/parse-clauses.c
clang/test/ParserOpenACC/parse-constructs.c
clang/test/SemaOpenACC/combined-construct-async-clause.cpp
clang/test/SemaOpenACC/combined-construct-wait-clause.cpp
clang/test/SemaOpenACC/compute-construct-async-clause.cpp
clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp
clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp
clang/test/SemaOpenACC/compute-construct-private-clause.c
clang/test/SemaOpenACC/compute-construct-reduction-clause.c
clang/test/SemaOpenACC/compute-construct-vector_length-clause.cpp
clang/test/SemaOpenACC/compute-construct-wait-clause.cpp
clang/test/SemaOpenACC/wait-construct.cpp
clang/tools/libclang/CIndex.cpp
clang/tools/libclang/CXCursor.cpp
Removed:
################################################################################
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 122118b8f37638..dfc562da88afee 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -2190,7 +2190,15 @@ enum CXCursorKind {
*/
CXCursor_OpenACCWaitConstruct = 327,
- CXCursor_LastStmt = CXCursor_OpenACCWaitConstruct,
+ /** OpenACC init Construct.
+ */
+ CXCursor_OpenACCInitConstruct = 328,
+
+ /** OpenACC shutdown Construct.
+ */
+ CXCursor_OpenACCShutdownConstruct = 329,
+
+ CXCursor_LastStmt = CXCursor_OpenACCShutdownConstruct,
/**
* Cursor that represents the translation unit itself.
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index d9a87b30062df8..f5b32ed51698e0 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -4076,6 +4076,10 @@ DEF_TRAVERSE_STMT(OpenACCWaitConstruct, {
TRY_TO(TraverseStmt(E));
TRY_TO(VisitOpenACCClauseList(S->clauses()));
})
+DEF_TRAVERSE_STMT(OpenACCInitConstruct,
+ { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
+DEF_TRAVERSE_STMT(OpenACCShutdownConstruct,
+ { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
// Traverse HLSL: Out argument expression
DEF_TRAVERSE_STMT(HLSLOutArgExpr, {})
diff --git a/clang/include/clang/AST/StmtOpenACC.h b/clang/include/clang/AST/StmtOpenACC.h
index 093393a81be9c7..e311eded5599bb 100644
--- a/clang/include/clang/AST/StmtOpenACC.h
+++ b/clang/include/clang/AST/StmtOpenACC.h
@@ -592,5 +592,85 @@ class OpenACCWaitConstruct final
return const_child_range(Begin, Begin + NumExprs);
}
};
+
+// This class represents an 'init' construct, which has just a clause list.
+class OpenACCInitConstruct final
+ : public OpenACCConstructStmt,
+ private llvm::TrailingObjects<OpenACCInitConstruct,
+ const OpenACCClause *> {
+ friend TrailingObjects;
+ OpenACCInitConstruct(unsigned NumClauses)
+ : OpenACCConstructStmt(OpenACCInitConstructClass,
+ OpenACCDirectiveKind::Init, SourceLocation{},
+ SourceLocation{}, SourceLocation{}) {
+ std::uninitialized_value_construct(
+ getTrailingObjects<const OpenACCClause *>(),
+ getTrailingObjects<const OpenACCClause *>() + NumClauses);
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ NumClauses));
+ }
+ OpenACCInitConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses)
+ : OpenACCConstructStmt(OpenACCInitConstructClass,
+ OpenACCDirectiveKind::Init, Start, DirectiveLoc,
+ End) {
+ std::uninitialized_copy(Clauses.begin(), Clauses.end(),
+ getTrailingObjects<const OpenACCClause *>());
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ Clauses.size()));
+ }
+
+public:
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OpenACCInitConstructClass;
+ }
+ static OpenACCInitConstruct *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses);
+ static OpenACCInitConstruct *Create(const ASTContext &C, SourceLocation Start,
+ SourceLocation DirectiveLoc,
+ SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses);
+};
+
+// This class represents a 'shutdown' construct, which has just a clause list.
+class OpenACCShutdownConstruct final
+ : public OpenACCConstructStmt,
+ private llvm::TrailingObjects<OpenACCShutdownConstruct,
+ const OpenACCClause *> {
+ friend TrailingObjects;
+ OpenACCShutdownConstruct(unsigned NumClauses)
+ : OpenACCConstructStmt(OpenACCShutdownConstructClass,
+ OpenACCDirectiveKind::Shutdown, SourceLocation{},
+ SourceLocation{}, SourceLocation{}) {
+ std::uninitialized_value_construct(
+ getTrailingObjects<const OpenACCClause *>(),
+ getTrailingObjects<const OpenACCClause *>() + NumClauses);
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ NumClauses));
+ }
+ OpenACCShutdownConstruct(SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses)
+ : OpenACCConstructStmt(OpenACCShutdownConstructClass,
+ OpenACCDirectiveKind::Shutdown, Start,
+ DirectiveLoc, End) {
+ std::uninitialized_copy(Clauses.begin(), Clauses.end(),
+ getTrailingObjects<const OpenACCClause *>());
+ setClauseList(MutableArrayRef(getTrailingObjects<const OpenACCClause *>(),
+ Clauses.size()));
+ }
+
+public:
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OpenACCShutdownConstructClass;
+ }
+ static OpenACCShutdownConstruct *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses);
+ static OpenACCShutdownConstruct *
+ Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End, ArrayRef<const OpenACCClause *> Clauses);
+};
+
} // namespace clang
#endif // LLVM_CLANG_AST_STMTOPENACC_H
diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h
index b6f16be7a5b98f..5383b53fdc491b 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -416,6 +416,8 @@ class TextNodeDumper
void VisitOpenACCExitDataConstruct(const OpenACCExitDataConstruct *S);
void VisitOpenACCHostDataConstruct(const OpenACCHostDataConstruct *S);
void VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *S);
+ void VisitOpenACCInitConstruct(const OpenACCInitConstruct *S);
+ void VisitOpenACCShutdownConstruct(const OpenACCShutdownConstruct *S);
void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *S);
void VisitEmbedExpr(const EmbedExpr *S);
void VisitAtomicExpr(const AtomicExpr *AE);
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index de34bcbf9ad4a6..8d19e9030ac2e3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12669,8 +12669,8 @@ def err_acc_int_expr_requires_integer
def err_acc_int_expr_incomplete_class_type
: Error<"OpenACC integer expression has incomplete class type %0">;
def err_acc_int_expr_explicit_conversion
- : Error<"OpenACC integer expression type %0 requires explicit conversion "
- "to %1">;
+ : Error<"OpenACC integer expression requires explicit conversion "
+ "from %0 to %1">;
def note_acc_int_expr_conversion
: Note<"conversion to %select{integral|enumeration}0 type %1">;
def err_acc_int_expr_multiple_conversions
diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index 6c7314b06d858a..31280df93e4c6e 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -313,6 +313,8 @@ def OpenACCEnterDataConstruct : StmtNode<OpenACCConstructStmt>;
def OpenACCExitDataConstruct : StmtNode<OpenACCConstructStmt>;
def OpenACCHostDataConstruct : StmtNode<OpenACCAssociatedStmtConstruct>;
def OpenACCWaitConstruct : StmtNode<OpenACCConstructStmt>;
+def OpenACCInitConstruct : StmtNode<OpenACCConstructStmt>;
+def OpenACCShutdownConstruct : StmtNode<OpenACCConstructStmt>;
// OpenACC Additional Expressions.
def OpenACCAsteriskSizeExpr : StmtNode<Expr>;
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 57e27c373bffa1..dfd82afad40070 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -2022,6 +2022,8 @@ enum StmtCode {
STMT_OPENACC_EXIT_DATA_CONSTRUCT,
STMT_OPENACC_HOST_DATA_CONSTRUCT,
STMT_OPENACC_WAIT_CONSTRUCT,
+ STMT_OPENACC_INIT_CONSTRUCT,
+ STMT_OPENACC_SHUTDOWN_CONSTRUCT,
// HLSL Constructs
EXPR_HLSL_OUT_ARG,
diff --git a/clang/lib/AST/StmtOpenACC.cpp b/clang/lib/AST/StmtOpenACC.cpp
index 6d9f267702e37d..e6d76ea30f0294 100644
--- a/clang/lib/AST/StmtOpenACC.cpp
+++ b/clang/lib/AST/StmtOpenACC.cpp
@@ -225,3 +225,43 @@ OpenACCWaitConstruct *OpenACCWaitConstruct::Create(
QueuesLoc, QueueIdExprs, RParenLoc, End, Clauses);
return Inst;
}
+OpenACCInitConstruct *OpenACCInitConstruct::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses) {
+ void *Mem =
+ C.Allocate(OpenACCInitConstruct::totalSizeToAlloc<const OpenACCClause *>(
+ NumClauses));
+ auto *Inst = new (Mem) OpenACCInitConstruct(NumClauses);
+ return Inst;
+}
+
+OpenACCInitConstruct *
+OpenACCInitConstruct::Create(const ASTContext &C, SourceLocation Start,
+ SourceLocation DirectiveLoc, SourceLocation End,
+ ArrayRef<const OpenACCClause *> Clauses) {
+ void *Mem =
+ C.Allocate(OpenACCInitConstruct::totalSizeToAlloc<const OpenACCClause *>(
+ Clauses.size()));
+ auto *Inst =
+ new (Mem) OpenACCInitConstruct(Start, DirectiveLoc, End, Clauses);
+ return Inst;
+}
+OpenACCShutdownConstruct *
+OpenACCShutdownConstruct::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses) {
+ void *Mem = C.Allocate(
+ OpenACCShutdownConstruct::totalSizeToAlloc<const OpenACCClause *>(
+ NumClauses));
+ auto *Inst = new (Mem) OpenACCShutdownConstruct(NumClauses);
+ return Inst;
+}
+
+OpenACCShutdownConstruct *OpenACCShutdownConstruct::Create(
+ const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc,
+ SourceLocation End, ArrayRef<const OpenACCClause *> Clauses) {
+ void *Mem = C.Allocate(
+ OpenACCShutdownConstruct::totalSizeToAlloc<const OpenACCClause *>(
+ Clauses.size()));
+ auto *Inst =
+ new (Mem) OpenACCShutdownConstruct(Start, DirectiveLoc, End, Clauses);
+ return Inst;
+}
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index ecc9b6e35db72d..c5d19f70fc6ea0 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -127,6 +127,8 @@ namespace {
void PrintOMPExecutableDirective(OMPExecutableDirective *S,
bool ForceNoStmt = false);
void PrintFPPragmas(CompoundStmt *S);
+ void PrintOpenACCClauseList(OpenACCConstructStmt *S);
+ void PrintOpenACCConstruct(OpenACCConstructStmt *S);
void PrintExpr(Expr *E) {
if (E)
@@ -1155,87 +1157,52 @@ void StmtPrinter::VisitOMPTargetParallelGenericLoopDirective(
//===----------------------------------------------------------------------===//
// OpenACC construct printing methods
//===----------------------------------------------------------------------===//
-void StmtPrinter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
- Indent() << "#pragma acc " << S->getDirectiveKind();
-
+void StmtPrinter::PrintOpenACCClauseList(OpenACCConstructStmt *S) {
if (!S->clauses().empty()) {
OS << ' ';
OpenACCClausePrinter Printer(OS, Policy);
Printer.VisitClauseList(S->clauses());
}
+}
+void StmtPrinter::PrintOpenACCConstruct(OpenACCConstructStmt *S) {
+ Indent() << "#pragma acc " << S->getDirectiveKind();
+ PrintOpenACCClauseList(S);
OS << '\n';
-
+}
+void StmtPrinter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
+ PrintOpenACCConstruct(S);
PrintStmt(S->getStructuredBlock());
}
void StmtPrinter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) {
- Indent() << "#pragma acc loop";
-
- if (!S->clauses().empty()) {
- OS << ' ';
- OpenACCClausePrinter Printer(OS, Policy);
- Printer.VisitClauseList(S->clauses());
- }
- OS << '\n';
-
+ PrintOpenACCConstruct(S);
PrintStmt(S->getLoop());
}
void StmtPrinter::VisitOpenACCCombinedConstruct(OpenACCCombinedConstruct *S) {
- Indent() << "#pragma acc " << S->getDirectiveKind();
- if (!S->clauses().empty()) {
- OS << ' ';
- OpenACCClausePrinter Printer(OS, Policy);
- Printer.VisitClauseList(S->clauses());
- }
- OS << '\n';
-
+ PrintOpenACCConstruct(S);
PrintStmt(S->getLoop());
}
void StmtPrinter::VisitOpenACCDataConstruct(OpenACCDataConstruct *S) {
- Indent() << "#pragma acc data";
-
- if (!S->clauses().empty()) {
- OS << ' ';
- OpenACCClausePrinter Printer(OS, Policy);
- Printer.VisitClauseList(S->clauses());
- }
- OS << '\n';
-
+ PrintOpenACCConstruct(S);
+ PrintStmt(S->getStructuredBlock());
+}
+void StmtPrinter::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) {
+ PrintOpenACCConstruct(S);
PrintStmt(S->getStructuredBlock());
}
void StmtPrinter::VisitOpenACCEnterDataConstruct(OpenACCEnterDataConstruct *S) {
- Indent() << "#pragma acc enter data";
-
- if (!S->clauses().empty()) {
- OS << ' ';
- OpenACCClausePrinter Printer(OS, Policy);
- Printer.VisitClauseList(S->clauses());
- }
- OS << '\n';
+ PrintOpenACCConstruct(S);
}
void StmtPrinter::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) {
- Indent() << "#pragma acc exit data";
-
- if (!S->clauses().empty()) {
- OS << ' ';
- OpenACCClausePrinter Printer(OS, Policy);
- Printer.VisitClauseList(S->clauses());
- }
- OS << '\n';
+ PrintOpenACCConstruct(S);
}
-void StmtPrinter::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) {
- Indent() << "#pragma acc host_data";
-
- if (!S->clauses().empty()) {
- OS << ' ';
- OpenACCClausePrinter Printer(OS, Policy);
- Printer.VisitClauseList(S->clauses());
- }
- OS << '\n';
-
- PrintStmt(S->getStructuredBlock());
+void StmtPrinter::VisitOpenACCInitConstruct(OpenACCInitConstruct *S) {
+ PrintOpenACCConstruct(S);
+}
+void StmtPrinter::VisitOpenACCShutdownConstruct(OpenACCShutdownConstruct *S) {
+ PrintOpenACCConstruct(S);
}
void StmtPrinter::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) {
@@ -1258,11 +1225,7 @@ void StmtPrinter::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) {
OS << ")";
}
- if (!S->clauses().empty()) {
- OS << ' ';
- OpenACCClausePrinter Printer(OS, Policy);
- Printer.VisitClauseList(S->clauses());
- }
+ PrintOpenACCClauseList(S);
OS << '\n';
}
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index fccd97dca23af2..4c4ecd791c48f2 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -2751,6 +2751,19 @@ void StmtProfiler::VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *S) {
P.VisitOpenACCClauseList(S->clauses());
}
+void StmtProfiler::VisitOpenACCInitConstruct(const OpenACCInitConstruct *S) {
+ VisitStmt(S);
+ OpenACCClauseProfiler P{*this};
+ P.VisitOpenACCClauseList(S->clauses());
+}
+
+void StmtProfiler::VisitOpenACCShutdownConstruct(
+ const OpenACCShutdownConstruct *S) {
+ VisitStmt(S);
+ OpenACCClauseProfiler P{*this};
+ P.VisitOpenACCClauseList(S->clauses());
+}
+
void StmtProfiler::VisitHLSLOutArgExpr(const HLSLOutArgExpr *S) {
VisitStmt(S);
}
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 7cdffbe20e575a..f9cbdf6916dcb1 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -2963,6 +2963,13 @@ void TextNodeDumper::VisitOpenACCHostDataConstruct(
void TextNodeDumper::VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *S) {
OS << " " << S->getDirectiveKind();
}
+void TextNodeDumper::VisitOpenACCInitConstruct(const OpenACCInitConstruct *S) {
+ OS << " " << S->getDirectiveKind();
+}
+void TextNodeDumper::VisitOpenACCShutdownConstruct(
+ const OpenACCShutdownConstruct *S) {
+ OS << " " << S->getDirectiveKind();
+}
void TextNodeDumper::VisitEmbedExpr(const EmbedExpr *S) {
AddChild("begin", [=] { OS << S->getStartingElementPos(); });
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 6c604f44e283be..3974739d2abb47 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -473,6 +473,12 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
case Stmt::OpenACCWaitConstructClass:
EmitOpenACCWaitConstruct(cast<OpenACCWaitConstruct>(*S));
break;
+ case Stmt::OpenACCInitConstructClass:
+ EmitOpenACCInitConstruct(cast<OpenACCInitConstruct>(*S));
+ break;
+ case Stmt::OpenACCShutdownConstructClass:
+ EmitOpenACCShutdownConstruct(cast<OpenACCShutdownConstruct>(*S));
+ break;
}
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 4d4139180e100f..1a5c42f8f974d0 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4123,6 +4123,16 @@ class CodeGenFunction : public CodeGenTypeCache {
// but in the future we will implement some sort of IR.
}
+ void EmitOpenACCInitConstruct(const OpenACCInitConstruct &S) {
+ // TODO OpenACC: Implement this. It is currently implemented as a 'no-op',
+ // but in the future we will implement some sort of IR.
+ }
+
+ void EmitOpenACCShutdownConstruct(const OpenACCShutdownConstruct &S) {
+ // TODO OpenACC: Implement this. It is currently implemented as a 'no-op',
+ // but in the future we will implement some sort of IR.
+ }
+
//===--------------------------------------------------------------------===//
// LValue Expression Emission
//===--------------------------------------------------------------------===//
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 5da34a2f5db923..31ec0c7c1d718d 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -574,6 +574,8 @@ bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) {
case OpenACCDirectiveKind::EnterData:
case OpenACCDirectiveKind::ExitData:
case OpenACCDirectiveKind::Wait:
+ case OpenACCDirectiveKind::Init:
+ case OpenACCDirectiveKind::Shutdown:
return false;
case OpenACCDirectiveKind::Parallel:
case OpenACCDirectiveKind::Serial:
@@ -606,6 +608,8 @@ unsigned getOpenACCScopeFlags(OpenACCDirectiveKind DirKind) {
case OpenACCDirectiveKind::ExitData:
case OpenACCDirectiveKind::HostData:
case OpenACCDirectiveKind::Wait:
+ case OpenACCDirectiveKind::Init:
+ case OpenACCDirectiveKind::Shutdown:
return 0;
case OpenACCDirectiveKind::Invalid:
llvm_unreachable("Shouldn't be creating a scope for an invalid construct");
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index 505cc5e153fa70..ac3666394d0e86 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -1399,6 +1399,8 @@ CanThrowResult Sema::canThrow(const Stmt *S) {
case Stmt::OpenACCEnterDataConstructClass:
case Stmt::OpenACCExitDataConstructClass:
case Stmt::OpenACCWaitConstructClass:
+ case Stmt::OpenACCInitConstructClass:
+ case Stmt::OpenACCShutdownConstructClass:
// These expressions can never throw.
return CT_Cannot;
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index aa9097bfa17436..618c0f62576402 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -574,7 +574,9 @@ bool checkValidAfterDeviceType(
bool isDirectiveKindImplemented(OpenACCDirectiveKind DK) {
return isOpenACCComputeDirectiveKind(DK) ||
isOpenACCCombinedDirectiveKind(DK) || isOpenACCDataDirectiveKind(DK) ||
- DK == OpenACCDirectiveKind::Loop || DK == OpenACCDirectiveKind::Wait;
+ DK == OpenACCDirectiveKind::Loop || DK == OpenACCDirectiveKind::Wait ||
+ DK == OpenACCDirectiveKind::Init ||
+ DK == OpenACCDirectiveKind::Shutdown;
}
class SemaOpenACCClauseVisitor {
@@ -699,7 +701,10 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause(
// sense. Prose DOES exist for 'data' and 'host_data', 'enter data' and 'exit
// data' both don't, but other implmementations do this. OpenACC issue 519
// filed for the latter two.
- if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
+ // GCC allows this on init/shutdown, presumably for good reason, so we do too.
+ if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Init &&
+ Clause.getDirectiveKind() != OpenACCDirectiveKind::Shutdown &&
+ checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause))
return nullptr;
// The parser has ensured that we have a proper condition expr, so there
@@ -1868,6 +1873,8 @@ bool PreserveLoopRAIIDepthInAssociatedStmtRAII(OpenACCDirectiveKind DK) {
case OpenACCDirectiveKind::EnterData:
case OpenACCDirectiveKind::ExitData:
case OpenACCDirectiveKind::Wait:
+ case OpenACCDirectiveKind::Init:
+ case OpenACCDirectiveKind::Shutdown:
llvm_unreachable("Doesn't have an associated stmt");
default:
case OpenACCDirectiveKind::Invalid:
@@ -2294,6 +2301,8 @@ void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K,
case OpenACCDirectiveKind::EnterData:
case OpenACCDirectiveKind::ExitData:
case OpenACCDirectiveKind::HostData:
+ case OpenACCDirectiveKind::Init:
+ case OpenACCDirectiveKind::Shutdown:
// Nothing to do here, there is no real legalization that needs to happen
// here as these constructs do not take any arguments.
break;
@@ -3682,6 +3691,14 @@ StmtResult SemaOpenACC::ActOnEndStmtDirective(
getASTContext(), StartLoc, DirLoc, LParenLoc, Exprs.front(), MiscLoc,
Exprs.drop_front(), RParenLoc, EndLoc, Clauses);
}
+ case OpenACCDirectiveKind::Init: {
+ return OpenACCInitConstruct::Create(getASTContext(), StartLoc, DirLoc,
+ EndLoc, Clauses);
+ }
+ case OpenACCDirectiveKind::Shutdown: {
+ return OpenACCShutdownConstruct::Create(getASTContext(), StartLoc, DirLoc,
+ EndLoc, Clauses);
+ }
}
llvm_unreachable("Unhandled case in directive handling?");
}
@@ -3695,6 +3712,8 @@ StmtResult SemaOpenACC::ActOnAssociatedStmt(
case OpenACCDirectiveKind::EnterData:
case OpenACCDirectiveKind::ExitData:
case OpenACCDirectiveKind::Wait:
+ case OpenACCDirectiveKind::Init:
+ case OpenACCDirectiveKind::Shutdown:
llvm_unreachable(
"these don't have associated statements, so shouldn't get here");
case OpenACCDirectiveKind::Parallel:
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index c097465374cba8..686132dbc5f5d4 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4151,6 +4151,24 @@ class TreeTransform {
SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, StrBlock);
}
+ StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
+ SourceLocation DirLoc,
+ SourceLocation EndLoc,
+ ArrayRef<OpenACCClause *> Clauses) {
+ return getSema().OpenACC().ActOnEndStmtDirective(
+ OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
+ SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
+ }
+
+ StmtResult
+ RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
+ SourceLocation DirLoc, SourceLocation EndLoc,
+ ArrayRef<OpenACCClause *> Clauses) {
+ return getSema().OpenACC().ActOnEndStmtDirective(
+ OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
+ SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
+ }
+
StmtResult RebuildOpenACCWaitConstruct(
SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
@@ -12348,6 +12366,40 @@ StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
TransformedClauses, StrBlock);
}
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
+ getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
+
+ llvm::SmallVector<OpenACCClause *> TransformedClauses =
+ getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
+ C->clauses());
+ if (getSema().OpenACC().ActOnStartStmtDirective(
+ C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
+ return StmtError();
+
+ return getDerived().RebuildOpenACCInitConstruct(
+ C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
+ TransformedClauses);
+}
+
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
+ OpenACCShutdownConstruct *C) {
+ getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
+
+ llvm::SmallVector<OpenACCClause *> TransformedClauses =
+ getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
+ C->clauses());
+ if (getSema().OpenACC().ActOnStartStmtDirective(
+ C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
+ return StmtError();
+
+ return getDerived().RebuildOpenACCShutdownConstruct(
+ C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
+ TransformedClauses);
+}
+
template <typename Derived>
StmtResult
TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 8fe0412706ce3e..9e8cf19a6f0f72 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2865,6 +2865,16 @@ void ASTStmtReader::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) {
VisitOpenACCConstructStmt(S);
}
+void ASTStmtReader::VisitOpenACCInitConstruct(OpenACCInitConstruct *S) {
+ VisitStmt(S);
+ VisitOpenACCConstructStmt(S);
+}
+
+void ASTStmtReader::VisitOpenACCShutdownConstruct(OpenACCShutdownConstruct *S) {
+ VisitStmt(S);
+ VisitOpenACCConstructStmt(S);
+}
+
void ASTStmtReader::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) {
VisitStmt(S);
VisitOpenACCAssociatedStmtConstruct(S);
@@ -4387,6 +4397,16 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = OpenACCWaitConstruct::CreateEmpty(Context, NumExprs, NumClauses);
break;
}
+ case STMT_OPENACC_INIT_CONSTRUCT: {
+ unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
+ S = OpenACCInitConstruct::CreateEmpty(Context, NumClauses);
+ break;
+ }
+ case STMT_OPENACC_SHUTDOWN_CONSTRUCT: {
+ unsigned NumClauses = Record[ASTStmtReader::NumStmtFields];
+ S = OpenACCShutdownConstruct::CreateEmpty(Context, NumClauses);
+ break;
+ }
case EXPR_REQUIRES: {
unsigned numLocalParameters = Record[ASTStmtReader::NumExprFields];
unsigned numRequirement = Record[ASTStmtReader::NumExprFields + 1];
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index f13443d18b612a..1d42b43c3e2ca0 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -2945,6 +2945,18 @@ void ASTStmtWriter::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) {
Code = serialization::STMT_OPENACC_EXIT_DATA_CONSTRUCT;
}
+void ASTStmtWriter::VisitOpenACCInitConstruct(OpenACCInitConstruct *S) {
+ VisitStmt(S);
+ VisitOpenACCConstructStmt(S);
+ Code = serialization::STMT_OPENACC_INIT_CONSTRUCT;
+}
+
+void ASTStmtWriter::VisitOpenACCShutdownConstruct(OpenACCShutdownConstruct *S) {
+ VisitStmt(S);
+ VisitOpenACCConstructStmt(S);
+ Code = serialization::STMT_OPENACC_SHUTDOWN_CONSTRUCT;
+}
+
void ASTStmtWriter::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) {
VisitStmt(S);
VisitOpenACCAssociatedStmtConstruct(S);
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 0a74a80a6a62f9..db385e891e762f 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1830,6 +1830,8 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
case Stmt::OpenACCExitDataConstructClass:
case Stmt::OpenACCHostDataConstructClass:
case Stmt::OpenACCWaitConstructClass:
+ case Stmt::OpenACCInitConstructClass:
+ case Stmt::OpenACCShutdownConstructClass:
case Stmt::OMPUnrollDirectiveClass:
case Stmt::OMPMetaDirectiveClass:
case Stmt::HLSLOutArgExprClass: {
diff --git a/clang/test/AST/ast-print-openacc-init-construct.cpp b/clang/test/AST/ast-print-openacc-init-construct.cpp
new file mode 100644
index 00000000000000..8bee2d84118f55
--- /dev/null
+++ b/clang/test/AST/ast-print-openacc-init-construct.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fopenacc -ast-print %s -o - | FileCheck %s
+
+unsigned Int;
+
+void uses() {
+// CHECK: #pragma acc init device_type(*) if(Int == 5)
+#pragma acc init device_type(*) device_num(Int) if (Int == 5)
+// CHECK: #pragma acc init device_type(*)
+// CHECK-NOT: device_num(Int)
+#pragma acc init device_type(*) device_num(Int)
+// CHECK: #pragma acc init device_type(*) if(Int == 5)
+#pragma acc init device_type(*) if (Int == 5)
+// CHECK: #pragma acc init device_type(SomeName)
+#pragma acc init device_type(SomeName)
+}
diff --git a/clang/test/AST/ast-print-openacc-shutdown-construct.cpp b/clang/test/AST/ast-print-openacc-shutdown-construct.cpp
new file mode 100644
index 00000000000000..c1da69dd82a237
--- /dev/null
+++ b/clang/test/AST/ast-print-openacc-shutdown-construct.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fopenacc -ast-print %s -o - | FileCheck %s
+
+unsigned Int;
+
+void uses() {
+// CHECK: #pragma acc shutdown device_type(*) if(Int == 5)
+#pragma acc shutdown device_type(*) device_num(Int) if (Int == 5)
+// CHECK: #pragma acc shutdown device_type(*)
+// CHECK-NOT: device_num(Int)
+#pragma acc shutdown device_type(*) device_num(Int)
+// CHECK: #pragma acc shutdown device_type(*) if(Int == 5)
+#pragma acc shutdown device_type(*) if (Int == 5)
+// CHECK: #pragma acc shutdown device_type(SomeName)
+#pragma acc shutdown device_type(SomeName)
+}
diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index 2e884c472c2ec1..7bd8edcee3db84 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -803,29 +803,23 @@ void IntExprParsing() {
#pragma acc parallel num_workers(returns_int())
{}
- // expected-error at +2{{expected '('}}
- // expected-warning at +1{{OpenACC construct 'init' not yet implemented, pragma ignored}}
+ // expected-error at +1{{expected '('}}
#pragma acc init device_num
- // expected-error at +2{{expected expression}}
- // expected-warning at +1{{OpenACC construct 'init' not yet implemented, pragma ignored}}
+ // expected-error at +1{{expected expression}}
#pragma acc init device_num()
- // expected-error at +2{{use of undeclared identifier 'invalid'}}
- // expected-warning at +1{{OpenACC construct 'init' not yet implemented, pragma ignored}}
+ // expected-error at +1{{use of undeclared identifier 'invalid'}}
#pragma acc init device_num(invalid)
- // expected-error at +3{{expected ')'}}
- // expected-note at +2{{to match this '('}}
- // expected-warning at +1{{OpenACC construct 'init' not yet implemented, pragma ignored}}
+ // expected-error at +2{{expected ')'}}
+ // expected-note at +1{{to match this '('}}
#pragma acc init device_num(5, 4)
- // expected-warning at +2{{OpenACC clause 'device_num' not yet implemented, clause ignored}}
- // expected-warning at +1{{OpenACC construct 'init' not yet implemented, pragma ignored}}
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented, clause ignored}}
#pragma acc init device_num(5)
- // expected-warning at +2{{OpenACC clause 'device_num' not yet implemented, clause ignored}}
- // expected-warning at +1{{OpenACC construct 'init' not yet implemented, pragma ignored}}
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented, clause ignored}}
#pragma acc init device_num(returns_int())
// expected-error at +2{{expected '('}}
diff --git a/clang/test/ParserOpenACC/parse-constructs.c b/clang/test/ParserOpenACC/parse-constructs.c
index 4a6c31cc9b0a9d..878c38e8bedc72 100644
--- a/clang/test/ParserOpenACC/parse-constructs.c
+++ b/clang/test/ParserOpenACC/parse-constructs.c
@@ -141,12 +141,10 @@ void func() {
// expected-warning at +1{{OpenACC construct 'declare' not yet implemented, pragma ignored}}
#pragma acc declare clause list
for(;;){}
- // expected-error at +2{{invalid OpenACC clause 'clause'}}
- // expected-warning at +1{{OpenACC construct 'init' not yet implemented, pragma ignored}}
+ // expected-error at +1{{invalid OpenACC clause 'clause'}}
#pragma acc init clause list
for(;;){}
- // expected-error at +2{{invalid OpenACC clause 'clause'}}
- // expected-warning at +1{{OpenACC construct 'shutdown' not yet implemented, pragma ignored}}
+ // expected-error at +1{{invalid OpenACC clause 'clause'}}
#pragma acc shutdown clause list
for(;;){}
// expected-error at +2{{invalid OpenACC clause 'clause'}}
diff --git a/clang/test/SemaOpenACC/combined-construct-async-clause.cpp b/clang/test/SemaOpenACC/combined-construct-async-clause.cpp
index 872586acbaffa2..c54f340cdfd964 100644
--- a/clang/test/SemaOpenACC/combined-construct-async-clause.cpp
+++ b/clang/test/SemaOpenACC/combined-construct-async-clause.cpp
@@ -48,7 +48,7 @@ void Test() {
#pragma acc parallel loop async(Convert)
for (int i = 5; i < 10; ++i);
- // expected-error at +2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc kernels loop async(Explicit)
for (int i = 5; i < 10; ++i);
@@ -94,12 +94,12 @@ void TestInst() {
#pragma acc kernels loop async(T::ACValue)
for (int i = 5; i < 10; ++i);
- // expected-error at +2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc parallel loop async(HasInt::EXValue)
for (int i = 5; i < 10; ++i);
- // expected-error at +2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc kernels loop async(T::EXValue)
for (int i = 5; i < 10; ++i);
diff --git a/clang/test/SemaOpenACC/combined-construct-wait-clause.cpp b/clang/test/SemaOpenACC/combined-construct-wait-clause.cpp
index 9ce04290cbe5a7..e0411925e9f206 100644
--- a/clang/test/SemaOpenACC/combined-construct-wait-clause.cpp
+++ b/clang/test/SemaOpenACC/combined-construct-wait-clause.cpp
@@ -18,7 +18,7 @@ void Test() {
#pragma acc parallel loop wait(Ambiguous)
for (unsigned i = 0; i < 5; ++i);
- // expected-error at +2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc parallel loop wait(4, Explicit, 5)
for (unsigned i = 0; i < 5; ++i);
@@ -29,12 +29,12 @@ void Test() {
#pragma acc parallel loop wait(queues: Ambiguous, 5)
for (unsigned i = 0; i < 5; ++i);
- // expected-error at +2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc parallel loop wait(devnum: Explicit: 5)
for (unsigned i = 0; i < 5; ++i);
- // expected-error at +2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc parallel loop wait(devnum: Explicit:queues: 5)
for (unsigned i = 0; i < 5; ++i);
@@ -70,7 +70,7 @@ void TestInst() {
#pragma acc parallel loop wait(devnum:T::value :queues:T::ACValue)
for (unsigned i = 0; i < 5; ++i);
- // expected-error at +5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
// expected-error at +3{{multiple conversions from expression type 'const AmbiguousConvert' to an integral type}}
// expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
@@ -78,7 +78,7 @@ void TestInst() {
#pragma acc parallel loop wait(devnum:T::EXValue :queues:T::ACValue)
for (unsigned i = 0; i < 5; ++i);
- // expected-error at +5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
// expected-error at +3{{multiple conversions from expression type 'const AmbiguousConvert' to an integral type}}
// expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
@@ -86,7 +86,7 @@ void TestInst() {
#pragma acc parallel loop wait(T::EXValue, T::ACValue)
for (unsigned i = 0; i < 5; ++i);
- // expected-error at +5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
// expected-error at +3{{multiple conversions from expression type 'const AmbiguousConvert' to an integral type}}
// expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
diff --git a/clang/test/SemaOpenACC/compute-construct-async-clause.cpp b/clang/test/SemaOpenACC/compute-construct-async-clause.cpp
index a5da7c8f4e56ec..44b1540a934c29 100644
--- a/clang/test/SemaOpenACC/compute-construct-async-clause.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-async-clause.cpp
@@ -46,7 +46,7 @@ void Test() {
#pragma acc parallel async(Convert)
while(1);
- // expected-error at +2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc kernels async(Explicit)
while(1);
@@ -92,12 +92,12 @@ void TestInst() {
#pragma acc kernels async(T::ACValue)
while (1);
- // expected-error at +2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc parallel async(HasInt::EXValue)
while (1);
- // expected-error at +2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc kernels async(T::EXValue)
while (1);
diff --git a/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp
index c50f52afda7c1c..c6dbe4db2be647 100644
--- a/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-num_gangs-clause.cpp
@@ -74,20 +74,20 @@ void Test() {
#pragma acc parallel num_gangs(SomeE, NC)
while(1);
- // expected-error at +3{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +3{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
// expected-error at +1{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}}
#pragma acc parallel num_gangs(Explicit, NC)
while(1);
- // expected-error at +4{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +4{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
// expected-error at +2{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}}
// expected-error at +1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}}
#pragma acc serial num_gangs(Explicit, NC)
while(1);
- // expected-error at +6{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +6{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
// expected-error at +4{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}}
// expected-error at +3{{multiple conversions from expression type 'struct AmbiguousConvert' to an integral type}}
@@ -96,7 +96,7 @@ void Test() {
#pragma acc parallel num_gangs(Explicit, NC, Ambiguous)
while(1);
- // expected-error at +7{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +7{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
// expected-error at +5{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}}
// expected-error at +4{{multiple conversions from expression type 'struct AmbiguousConvert' to an integral type}}
diff --git a/clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp b/clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp
index 9449b77d092f4a..c73f421222e866 100644
--- a/clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-num_workers-clause.cpp
@@ -44,7 +44,7 @@ void Test() {
#pragma acc parallel num_workers(Convert)
while(1);
- // expected-error at +2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc kernels num_workers(Explicit)
while(1);
@@ -90,12 +90,12 @@ void TestInst() {
#pragma acc kernels num_workers(T::ACValue)
while (1);
- // expected-error at +2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc parallel num_workers(HasInt::EXValue)
while (1);
- // expected-error at +2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc kernels num_workers(T::EXValue)
while (1);
diff --git a/clang/test/SemaOpenACC/compute-construct-private-clause.c b/clang/test/SemaOpenACC/compute-construct-private-clause.c
index d979fd909f11cf..a40d84c669d9ad 100644
--- a/clang/test/SemaOpenACC/compute-construct-private-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-private-clause.c
@@ -135,8 +135,7 @@ void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete Compo
#pragma acc parallel private((float)ArrayParam[2])
while(1);
- // expected-error at +2{{OpenACC 'private' clause is not valid on 'init' directive}}
- // expected-warning at +1{{OpenACC construct 'init' not yet implemented}}
+ // expected-error at +1{{OpenACC 'private' clause is not valid on 'init' directive}}
#pragma acc init private(LocalInt)
for(;;);
}
diff --git a/clang/test/SemaOpenACC/compute-construct-reduction-clause.c b/clang/test/SemaOpenACC/compute-construct-reduction-clause.c
index fcc4ca2655c20a..4d426cf189fca7 100644
--- a/clang/test/SemaOpenACC/compute-construct-reduction-clause.c
+++ b/clang/test/SemaOpenACC/compute-construct-reduction-clause.c
@@ -105,8 +105,7 @@ void uses(unsigned Parm) {
#pragma acc parallel reduction(&:HA.array[1:2])
while (1);
- // expected-error at +2{{OpenACC 'reduction' clause is not valid on 'init' directive}}
- // expected-warning at +1{{OpenACC construct 'init' not yet implemented}}
+ // expected-error at +1{{OpenACC 'reduction' clause is not valid on 'init' directive}}
#pragma acc init reduction(+:I)
for(;;);
}
diff --git a/clang/test/SemaOpenACC/compute-construct-vector_length-clause.cpp b/clang/test/SemaOpenACC/compute-construct-vector_length-clause.cpp
index f6c5dde1a02355..f2bbe0f022a07d 100644
--- a/clang/test/SemaOpenACC/compute-construct-vector_length-clause.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-vector_length-clause.cpp
@@ -44,7 +44,7 @@ void Test() {
#pragma acc parallel vector_length(Convert)
while(1);
- // expected-error at +2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc kernels vector_length(Explicit)
while(1);
@@ -90,12 +90,12 @@ void TestInst() {
#pragma acc kernels vector_length(T::ACValue)
while (1);
- // expected-error at +2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc parallel vector_length(HasInt::EXValue)
while (1);
- // expected-error at +2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc kernels vector_length(T::EXValue)
while (1);
diff --git a/clang/test/SemaOpenACC/compute-construct-wait-clause.cpp b/clang/test/SemaOpenACC/compute-construct-wait-clause.cpp
index 94f669be0f672d..fbe40ce5f31c15 100644
--- a/clang/test/SemaOpenACC/compute-construct-wait-clause.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-wait-clause.cpp
@@ -18,7 +18,7 @@ void Test() {
#pragma acc parallel wait(Ambiguous)
while (true);
- // expected-error at +2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc parallel wait(4, Explicit, 5)
while (true);
@@ -29,12 +29,12 @@ void Test() {
#pragma acc parallel wait(queues: Ambiguous, 5)
while (true);
- // expected-error at +2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc parallel wait(devnum: Explicit: 5)
while (true);
- // expected-error at +2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc parallel wait(devnum: Explicit:queues: 5)
while (true);
@@ -70,7 +70,7 @@ void TestInst() {
#pragma acc parallel wait(devnum:T::value :queues:T::ACValue)
while (true);
- // expected-error at +5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
// expected-error at +3{{multiple conversions from expression type 'const AmbiguousConvert' to an integral type}}
// expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
@@ -78,7 +78,7 @@ void TestInst() {
#pragma acc parallel wait(devnum:T::EXValue :queues:T::ACValue)
while (true);
- // expected-error at +5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
// expected-error at +3{{multiple conversions from expression type 'const AmbiguousConvert' to an integral type}}
// expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
@@ -86,7 +86,7 @@ void TestInst() {
#pragma acc parallel wait(T::EXValue, T::ACValue)
while (true);
- // expected-error at +5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
// expected-error at +3{{multiple conversions from expression type 'const AmbiguousConvert' to an integral type}}
// expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
diff --git a/clang/test/SemaOpenACC/init-construct-ast.cpp b/clang/test/SemaOpenACC/init-construct-ast.cpp
new file mode 100644
index 00000000000000..793a4829d14b3f
--- /dev/null
+++ b/clang/test/SemaOpenACC/init-construct-ast.cpp
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s
+
+// Test this with PCH.
+// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s
+// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s
+
+#ifndef PCH_HELPER
+#define PCH_HELPER
+
+int some_int();
+long some_long();
+void NormalFunc() {
+ // CHECK-LABEL: NormalFunc
+ // CHECK-NEXT: CompoundStmt
+
+#pragma acc init
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+#pragma acc init if (some_int() < some_long())
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} 'bool' '<'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}} 'long'
+ // CHECK-NEXT: CallExpr
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()'
+ // CHECK-NEXT: CallExpr
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr{{.*}}'some_long' 'long ()'
+#pragma acc init device_num(some_int())
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+#pragma acc init device_type(T)
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+ // CHECK-NEXT: device_type(T)
+#pragma acc init if (some_int() < some_long()) device_type(T) device_num(some_int())
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} 'bool' '<'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}} 'long'
+ // CHECK-NEXT: CallExpr
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()'
+ // CHECK-NEXT: CallExpr
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr{{.*}}'some_long' 'long ()'
+ // CHECK-NEXT: device_type(T)
+}
+
+template<typename T>
+void TemplFunc(T t) {
+ // CHECK-LABEL: FunctionTemplateDecl {{.*}}TemplFunc
+ // CHECK-NEXT: TemplateTypeParmDecl
+ // CHECK-NEXT: FunctionDecl{{.*}}TemplFunc
+ // CHECK-NEXT: ParmVarDecl{{.*}} t 'T'
+ // CHECK-NEXT: CompoundStmt
+
+#pragma acc init
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+#pragma acc init if (T::value > t)
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} '<dependent type>' '>'
+ // CHECK-NEXT: DependentScopeDeclRefExpr
+ // CHECK-NEXT: NestedNameSpecifier{{.*}} 'T'
+ // CHECK-NEXT: DeclRefExpr{{.*}} 't' 'T'
+#pragma acc init device_num(t)
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+#pragma acc init device_type(T)
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+ // CHECK-NEXT: device_type(T)
+#pragma acc init if (T::value > t) device_type(T) device_num(t)
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} '<dependent type>' '>'
+ // CHECK-NEXT: DependentScopeDeclRefExpr
+ // CHECK-NEXT: NestedNameSpecifier{{.*}} 'T'
+ // CHECK-NEXT: DeclRefExpr{{.*}} 't' 'T'
+ // CHECK-NEXT: device_type(T)
+
+ // Instantiation:
+ // CHECK-NEXT: FunctionDecl{{.*}} TemplFunc 'void (SomeStruct)' implicit_instantiation
+ // CHECK-NEXT: TemplateArgument type 'SomeStruct'
+ // CHECK-NEXT: RecordType{{.*}} 'SomeStruct'
+ // CHECK-NEXT: CXXRecord{{.*}} 'SomeStruct'
+ // CHECK-NEXT: ParmVarDecl{{.*}} t 'SomeStruct'
+ // CHECK-NEXT: CompoundStmt
+
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} 'bool' '>'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
+ // CHECK-NEXT: DeclRefExpr{{.*}}'value' 'const unsigned int'
+ // CHECK-NEXT: NestedNameSpecifier{{.*}} 'SomeStruct'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
+ // CHECK-NEXT: CXXMemberCallExpr{{.*}} 'unsigned int'
+ // CHECK-NEXT: MemberExpr{{.*}} .operator unsigned int
+ // CHECK-NEXT: DeclRefExpr{{.*}} 't' 'SomeStruct'
+
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+ // CHECK-NEXT: device_type(T)
+
+ // CHECK-NEXT: OpenACCInitConstruct{{.*}}init
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} 'bool' '>'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
+ // CHECK-NEXT: DeclRefExpr{{.*}}'value' 'const unsigned int'
+ // CHECK-NEXT: NestedNameSpecifier{{.*}} 'SomeStruct'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
+ // CHECK-NEXT: CXXMemberCallExpr{{.*}} 'unsigned int'
+ // CHECK-NEXT: MemberExpr{{.*}} .operator unsigned int
+ // CHECK-NEXT: DeclRefExpr{{.*}} 't' 'SomeStruct'
+}
+
+struct SomeStruct{
+ static constexpr unsigned value = 5;
+ operator unsigned();
+};
+
+void use() {
+ TemplFunc(SomeStruct{});
+}
+#endif
diff --git a/clang/test/SemaOpenACC/init-construct.cpp b/clang/test/SemaOpenACC/init-construct.cpp
new file mode 100644
index 00000000000000..152b27c0f3be1f
--- /dev/null
+++ b/clang/test/SemaOpenACC/init-construct.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+struct NotConvertible{} NC;
+short getS();
+int getI();
+
+struct AmbiguousConvert{
+ operator int(); // #AMBIG_INT
+ operator short(); // #AMBIG_SHORT
+ operator float();
+} Ambiguous;
+
+struct ExplicitConvertOnly {
+ explicit operator int() const; // #EXPL_CONV
+} Explicit;
+
+void uses() {
+#pragma acc init
+#pragma acc init if (getI() < getS())
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc init device_num(getI())
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc init device_type(SOMETHING) device_num(getI())
+#pragma acc init device_type(SOMETHING) if (getI() < getS())
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc init device_type(SOMETHING) device_num(getI()) if (getI() < getS())
+
+ // expected-error at +1{{value of type 'struct NotConvertible' is not contextually convertible to 'bool'}}
+#pragma acc init if (NC)
+
+ // expected-error at +1{{OpenACC clause 'device_num' requires expression of integer type ('struct NotConvertible' invalid)}}
+#pragma acc init device_num(NC)
+ // expected-error at +3{{multiple conversions from expression type 'struct AmbiguousConvert' to an integral type}}
+ // expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
+ // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}}
+#pragma acc init device_num(Ambiguous)
+ // expected-warning at +3{{OpenACC clause 'device_num' not yet implemented}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
+ // expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
+#pragma acc init device_num(Explicit)
+}
+
+template<typename T>
+void TestInst() {
+ T t;
+#pragma acc init
+#pragma acc init if (T::value < T{})
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc init device_type(SOMETHING) device_num(getI()) if (getI() < getS())
+ // expected-warning at +1 2{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc init device_type(SOMETHING) device_type(T) device_num(t) if (t < T::value) device_num(getI()) if (getI() < getS())
+
+
+ // expected-error at +1{{value of type 'const NotConvertible' is not contextually convertible to 'bool'}}
+#pragma acc init if (T::NCValue)
+
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc init device_num(T::NCValue)
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc init device_num(T::ACValue)
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc init device_num(T::EXValue)
+}
+
+struct HasStuff {
+ static constexpr AmbiguousConvert ACValue;
+ static constexpr ExplicitConvertOnly EXValue;
+ static constexpr NotConvertible NCValue;
+ static constexpr unsigned value = 5;
+ operator char();
+};
+
+void Inst() {
+ TestInst<HasStuff>(); // expected-note {{in instantiation of function template specialization}}
+}
diff --git a/clang/test/SemaOpenACC/shutdown-construct-ast.cpp b/clang/test/SemaOpenACC/shutdown-construct-ast.cpp
new file mode 100644
index 00000000000000..006f1c9e4c9968
--- /dev/null
+++ b/clang/test/SemaOpenACC/shutdown-construct-ast.cpp
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s
+
+// Test this with PCH.
+// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s
+// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s
+
+#ifndef PCH_HELPER
+#define PCH_HELPER
+
+int some_int();
+long some_long();
+void NormalFunc() {
+ // CHECK-LABEL: NormalFunc
+ // CHECK-NEXT: CompoundStmt
+
+#pragma acc shutdown
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+#pragma acc shutdown if (some_int() < some_long())
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} 'bool' '<'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}} 'long'
+ // CHECK-NEXT: CallExpr
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()'
+ // CHECK-NEXT: CallExpr
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr{{.*}}'some_long' 'long ()'
+#pragma acc shutdown device_num(some_int())
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+#pragma acc shutdown device_type(T)
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+ // CHECK-NEXT: device_type(T)
+#pragma acc shutdown if (some_int() < some_long()) device_type(T) device_num(some_int())
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} 'bool' '<'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}} 'long'
+ // CHECK-NEXT: CallExpr
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()'
+ // CHECK-NEXT: CallExpr
+ // CHECK-NEXT: ImplicitCastExpr
+ // CHECK-NEXT: DeclRefExpr{{.*}}'some_long' 'long ()'
+ // CHECK-NEXT: device_type(T)
+}
+
+template<typename T>
+void TemplFunc(T t) {
+ // CHECK-LABEL: FunctionTemplateDecl {{.*}}TemplFunc
+ // CHECK-NEXT: TemplateTypeParmDecl
+ // CHECK-NEXT: FunctionDecl{{.*}}TemplFunc
+ // CHECK-NEXT: ParmVarDecl{{.*}} t 'T'
+ // CHECK-NEXT: CompoundStmt
+
+#pragma acc shutdown
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+#pragma acc shutdown if (T::value > t)
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} '<dependent type>' '>'
+ // CHECK-NEXT: DependentScopeDeclRefExpr
+ // CHECK-NEXT: NestedNameSpecifier{{.*}} 'T'
+ // CHECK-NEXT: DeclRefExpr{{.*}} 't' 'T'
+#pragma acc shutdown device_num(t)
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+#pragma acc shutdown device_type(T)
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+ // CHECK-NEXT: device_type(T)
+#pragma acc shutdown if (T::value > t) device_type(T) device_num(t)
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} '<dependent type>' '>'
+ // CHECK-NEXT: DependentScopeDeclRefExpr
+ // CHECK-NEXT: NestedNameSpecifier{{.*}} 'T'
+ // CHECK-NEXT: DeclRefExpr{{.*}} 't' 'T'
+ // CHECK-NEXT: device_type(T)
+
+ // Instantiation:
+ // CHECK-NEXT: FunctionDecl{{.*}} TemplFunc 'void (SomeStruct)' implicit_instantiation
+ // CHECK-NEXT: TemplateArgument type 'SomeStruct'
+ // CHECK-NEXT: RecordType{{.*}} 'SomeStruct'
+ // CHECK-NEXT: CXXRecord{{.*}} 'SomeStruct'
+ // CHECK-NEXT: ParmVarDecl{{.*}} t 'SomeStruct'
+ // CHECK-NEXT: CompoundStmt
+
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} 'bool' '>'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
+ // CHECK-NEXT: DeclRefExpr{{.*}}'value' 'const unsigned int'
+ // CHECK-NEXT: NestedNameSpecifier{{.*}} 'SomeStruct'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
+ // CHECK-NEXT: CXXMemberCallExpr{{.*}} 'unsigned int'
+ // CHECK-NEXT: MemberExpr{{.*}} .operator unsigned int
+ // CHECK-NEXT: DeclRefExpr{{.*}} 't' 'SomeStruct'
+
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+ // CHECK-NEXT: device_type(T)
+
+ // CHECK-NEXT: OpenACCShutdownConstruct{{.*}}shutdown
+ // CHECK-NEXT: if clause
+ // CHECK-NEXT: BinaryOperator{{.*}} 'bool' '>'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
+ // CHECK-NEXT: DeclRefExpr{{.*}}'value' 'const unsigned int'
+ // CHECK-NEXT: NestedNameSpecifier{{.*}} 'SomeStruct'
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'unsigned int'
+ // CHECK-NEXT: CXXMemberCallExpr{{.*}} 'unsigned int'
+ // CHECK-NEXT: MemberExpr{{.*}} .operator unsigned int
+ // CHECK-NEXT: DeclRefExpr{{.*}} 't' 'SomeStruct'
+}
+
+struct SomeStruct{
+ static constexpr unsigned value = 5;
+ operator unsigned();
+};
+
+void use() {
+ TemplFunc(SomeStruct{});
+}
+#endif
diff --git a/clang/test/SemaOpenACC/shutdown-construct.cpp b/clang/test/SemaOpenACC/shutdown-construct.cpp
new file mode 100644
index 00000000000000..e4305883376c70
--- /dev/null
+++ b/clang/test/SemaOpenACC/shutdown-construct.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 %s -fopenacc -verify
+
+struct NotConvertible{} NC;
+short getS();
+int getI();
+
+struct AmbiguousConvert{
+ operator int(); // #AMBIG_INT
+ operator short(); // #AMBIG_SHORT
+ operator float();
+} Ambiguous;
+
+struct ExplicitConvertOnly {
+ explicit operator int() const; // #EXPL_CONV
+} Explicit;
+
+void uses() {
+#pragma acc shutdown
+#pragma acc shutdown if (getI() < getS())
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc shutdown device_num(getI())
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc shutdown device_type(SOMETHING) device_num(getI())
+#pragma acc shutdown device_type(SOMETHING) if (getI() < getS())
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc shutdown device_type(SOMETHING) device_num(getI()) if (getI() < getS())
+
+ // expected-error at +1{{value of type 'struct NotConvertible' is not contextually convertible to 'bool'}}
+#pragma acc shutdown if (NC)
+
+ // expected-error at +1{{OpenACC clause 'device_num' requires expression of integer type ('struct NotConvertible' invalid)}}
+#pragma acc shutdown device_num(NC)
+ // expected-error at +3{{multiple conversions from expression type 'struct AmbiguousConvert' to an integral type}}
+ // expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
+ // expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}}
+#pragma acc shutdown device_num(Ambiguous)
+ // expected-warning at +3{{OpenACC clause 'device_num' not yet implemented}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
+ // expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
+#pragma acc shutdown device_num(Explicit)
+}
+
+template<typename T>
+void TestInst() {
+ T t;
+#pragma acc shutdown
+#pragma acc shutdown if (T::value < T{})
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc shutdown device_type(SOMETHING) device_num(getI()) if (getI() < getS())
+ // expected-warning at +1 2{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc shutdown device_type(SOMETHING) device_type(T) device_num(t) if (t < T::value) device_num(getI()) if (getI() < getS())
+
+ // expected-error at +1{{value of type 'const NotConvertible' is not contextually convertible to 'bool'}}
+#pragma acc shutdown if (T::NCValue)
+
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc shutdown device_num(T::NCValue)
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc shutdown device_num(T::ACValue)
+ // expected-warning at +1{{OpenACC clause 'device_num' not yet implemented}}
+#pragma acc shutdown device_num(T::EXValue)
+}
+
+struct HasStuff {
+ static constexpr AmbiguousConvert ACValue;
+ static constexpr ExplicitConvertOnly EXValue;
+ static constexpr NotConvertible NCValue;
+ static constexpr unsigned value = 5;
+ operator char();
+};
+
+void Inst() {
+ TestInst<HasStuff>(); // expected-note {{in instantiation of function template specialization}}
+}
diff --git a/clang/test/SemaOpenACC/wait-construct.cpp b/clang/test/SemaOpenACC/wait-construct.cpp
index a68fc54b6e8f27..2de98762ea6007 100644
--- a/clang/test/SemaOpenACC/wait-construct.cpp
+++ b/clang/test/SemaOpenACC/wait-construct.cpp
@@ -35,7 +35,7 @@ void uses() {
// expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}}
#pragma acc wait(Ambiguous)
- // expected-error at +2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +2{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
#pragma acc wait(4, Explicit, 5)
@@ -61,7 +61,7 @@ void TestInst() {
// expected-note@#AMBIG_SHORT{{conversion to integral type 'short'}}
#pragma acc wait(devnum:T::value :queues:T::ACValue)
- // expected-error at +5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}}
+ // expected-error at +5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}}
// expected-note@#EXPL_CONV{{conversion to integral type 'int'}}
// expected-error at +3{{multiple conversions from expression type 'const AmbiguousConvert' to an integral type}}
// expected-note@#AMBIG_INT{{conversion to integral type 'int'}}
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 9bdc4c9f8ce238..140200a52b80b7 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2190,6 +2190,8 @@ class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void>,
void VisitOpenACCExitDataConstruct(const OpenACCExitDataConstruct *D);
void VisitOpenACCHostDataConstruct(const OpenACCHostDataConstruct *D);
void VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *D);
+ void VisitOpenACCInitConstruct(const OpenACCInitConstruct *D);
+ void VisitOpenACCShutdownConstruct(const OpenACCShutdownConstruct *D);
void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
void VisitOMPLoopDirective(const OMPLoopDirective *D);
@@ -3639,6 +3641,19 @@ void EnqueueVisitor::VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *C) {
EnqueueChildren(Clause);
}
+void EnqueueVisitor::VisitOpenACCInitConstruct(const OpenACCInitConstruct *C) {
+ EnqueueChildren(C);
+ for (auto *Clause : C->clauses())
+ EnqueueChildren(Clause);
+}
+
+void EnqueueVisitor::VisitOpenACCShutdownConstruct(
+ const OpenACCShutdownConstruct *C) {
+ EnqueueChildren(C);
+ for (auto *Clause : C->clauses())
+ EnqueueChildren(Clause);
+}
+
void EnqueueVisitor::VisitAnnotateAttr(const AnnotateAttr *A) {
EnqueueChildren(A);
}
@@ -6403,6 +6418,10 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
return cxstring::createRef("OpenACCHostDataConstruct");
case CXCursor_OpenACCWaitConstruct:
return cxstring::createRef("OpenACCWaitConstruct");
+ case CXCursor_OpenACCInitConstruct:
+ return cxstring::createRef("OpenACCInitConstruct");
+ case CXCursor_OpenACCShutdownConstruct:
+ return cxstring::createRef("OpenACCShutdownConstruct");
}
llvm_unreachable("Unhandled CXCursorKind");
diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index b9fd3b4c7f3645..f56e77b42f9d73 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -903,6 +903,12 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
case Stmt::OpenACCWaitConstructClass:
K = CXCursor_OpenACCWaitConstruct;
break;
+ case Stmt::OpenACCInitConstructClass:
+ K = CXCursor_OpenACCInitConstruct;
+ break;
+ case Stmt::OpenACCShutdownConstructClass:
+ K = CXCursor_OpenACCShutdownConstruct;
+ break;
case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
K = CXCursor_OMPTargetParallelGenericLoopDirective;
break;
More information about the cfe-commits
mailing list