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@+2{{expected '('}} - // expected-warning@+1{{OpenACC construct 'init' not yet implemented, pragma ignored}} + // expected-error@+1{{expected '('}} #pragma acc init device_num - // expected-error@+2{{expected expression}} - // expected-warning@+1{{OpenACC construct 'init' not yet implemented, pragma ignored}} + // expected-error@+1{{expected expression}} #pragma acc init device_num() - // expected-error@+2{{use of undeclared identifier 'invalid'}} - // expected-warning@+1{{OpenACC construct 'init' not yet implemented, pragma ignored}} + // expected-error@+1{{use of undeclared identifier 'invalid'}} #pragma acc init device_num(invalid) - // expected-error@+3{{expected ')'}} - // expected-note@+2{{to match this '('}} - // expected-warning@+1{{OpenACC construct 'init' not yet implemented, pragma ignored}} + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} #pragma acc init device_num(5, 4) - // expected-warning@+2{{OpenACC clause 'device_num' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'init' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented, clause ignored}} #pragma acc init device_num(5) - // expected-warning@+2{{OpenACC clause 'device_num' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'init' not yet implemented, pragma ignored}} + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented, clause ignored}} #pragma acc init device_num(returns_int()) // expected-error@+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@+1{{OpenACC construct 'declare' not yet implemented, pragma ignored}} #pragma acc declare clause list for(;;){} - // expected-error@+2{{invalid OpenACC clause 'clause'}} - // expected-warning@+1{{OpenACC construct 'init' not yet implemented, pragma ignored}} + // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc init clause list for(;;){} - // expected-error@+2{{invalid OpenACC clause 'clause'}} - // expected-warning@+1{{OpenACC construct 'shutdown' not yet implemented, pragma ignored}} + // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc shutdown clause list for(;;){} // expected-error@+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@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}} // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} // expected-error@+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@+5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}} // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} // expected-error@+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@+5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}} // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} // expected-error@+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@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+3{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+3{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}} // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} // expected-error@+1{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} #pragma acc parallel num_gangs(Explicit, NC) while(1); - // expected-error@+4{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+4{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}} // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} // expected-error@+2{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} // expected-error@+1{{OpenACC 'num_gangs' clause is not valid on 'serial' directive}} #pragma acc serial num_gangs(Explicit, NC) while(1); - // expected-error@+6{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+6{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}} // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} // expected-error@+4{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} // expected-error@+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@+7{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+7{{OpenACC integer expression requires explicit conversion from 'struct ExplicitConvertOnly' to 'int'}} // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} // expected-error@+5{{OpenACC clause 'num_gangs' requires expression of integer type ('struct NotConvertible' invalid)}} // expected-error@+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@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC 'private' clause is not valid on 'init' directive}} - // expected-warning@+1{{OpenACC construct 'init' not yet implemented}} + // expected-error@+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@+2{{OpenACC 'reduction' clause is not valid on 'init' directive}} - // expected-warning@+1{{OpenACC construct 'init' not yet implemented}} + // expected-error@+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@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}} // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} // expected-error@+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@+5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}} // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} // expected-error@+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@+5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}} // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} // expected-error@+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@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc init device_num(getI()) + // expected-warning@+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@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc init device_type(SOMETHING) device_num(getI()) if (getI() < getS()) + + // expected-error@+1{{value of type 'struct NotConvertible' is not contextually convertible to 'bool'}} +#pragma acc init if (NC) + + // expected-error@+1{{OpenACC clause 'device_num' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc init device_num(NC) + // expected-error@+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@+3{{OpenACC clause 'device_num' not yet implemented}} + // expected-error@+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@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc init device_type(SOMETHING) device_num(getI()) if (getI() < getS()) + // expected-warning@+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@+1{{value of type 'const NotConvertible' is not contextually convertible to 'bool'}} +#pragma acc init if (T::NCValue) + + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc init device_num(T::NCValue) + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc init device_num(T::ACValue) + // expected-warning@+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@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc shutdown device_num(getI()) + // expected-warning@+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@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc shutdown device_type(SOMETHING) device_num(getI()) if (getI() < getS()) + + // expected-error@+1{{value of type 'struct NotConvertible' is not contextually convertible to 'bool'}} +#pragma acc shutdown if (NC) + + // expected-error@+1{{OpenACC clause 'device_num' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc shutdown device_num(NC) + // expected-error@+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@+3{{OpenACC clause 'device_num' not yet implemented}} + // expected-error@+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@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc shutdown device_type(SOMETHING) device_num(getI()) if (getI() < getS()) + // expected-warning@+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@+1{{value of type 'const NotConvertible' is not contextually convertible to 'bool'}} +#pragma acc shutdown if (T::NCValue) + + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc shutdown device_num(T::NCValue) + // expected-warning@+1{{OpenACC clause 'device_num' not yet implemented}} +#pragma acc shutdown device_num(T::ACValue) + // expected-warning@+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@+2{{OpenACC integer expression type 'struct ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+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@+5{{OpenACC integer expression type 'const ExplicitConvertOnly' requires explicit conversion to 'int'}} + // expected-error@+5{{OpenACC integer expression requires explicit conversion from 'const ExplicitConvertOnly' to 'int'}} // expected-note@#EXPL_CONV{{conversion to integral type 'int'}} // expected-error@+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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits