https://github.com/kparzysz created https://github.com/llvm/llvm-project/pull/118878
This will be used to print the original directive source from the AST after splitting compound directives. >From 1447ec21597f752b29e367a46f06eecdf9c81dd7 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek <krzysztof.parzys...@amd.com> Date: Wed, 30 Oct 2024 13:34:21 -0500 Subject: [PATCH] [clang][OpenMP] Add AST node for root of compound directive This will be used to print the original directive source from the AST after splitting compound directives. --- clang/bindings/python/clang/cindex.py | 3 + clang/include/clang-c/Index.h | 4 ++ clang/include/clang/AST/RecursiveASTVisitor.h | 3 + clang/include/clang/AST/StmtOpenMP.h | 60 +++++++++++++++++++ clang/include/clang/AST/TextNodeDumper.h | 1 + clang/include/clang/Basic/StmtNodes.td | 1 + clang/include/clang/Sema/SemaOpenMP.h | 6 ++ .../include/clang/Serialization/ASTBitCodes.h | 1 + clang/lib/AST/StmtOpenMP.cpp | 15 +++++ clang/lib/AST/StmtPrinter.cpp | 6 ++ clang/lib/AST/StmtProfile.cpp | 5 ++ clang/lib/AST/TextNodeDumper.cpp | 7 +++ clang/lib/CodeGen/CGStmt.cpp | 4 ++ clang/lib/Sema/SemaExceptionSpec.cpp | 1 + clang/lib/Sema/SemaOpenMP.cpp | 7 +++ clang/lib/Sema/TreeTransform.h | 8 +++ clang/lib/Serialization/ASTReaderStmt.cpp | 15 +++++ clang/lib/Serialization/ASTWriterStmt.cpp | 7 +++ clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 1 + 19 files changed, 155 insertions(+) diff --git a/clang/bindings/python/clang/cindex.py b/clang/bindings/python/clang/cindex.py index 3ae7c479153690..5174e16f28f06d 100644 --- a/clang/bindings/python/clang/cindex.py +++ b/clang/bindings/python/clang/cindex.py @@ -1416,6 +1416,9 @@ def is_unexposed(self): # OpenMP opaque loop-associated directive. OMP_OPAQUE_LOOP_DIRECTIVE = 311 + # OpenMP compound root directive. + OMP_COMPOUND_ROOT_DIRECTIVE = 312 + # OpenACC Compute Construct. OPEN_ACC_COMPUTE_DIRECTIVE = 320 diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 5d1db153aaafed..02ce2b7690ef06 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2166,6 +2166,10 @@ enum CXCursorKind { */ CXCursor_OMPOpaqueLoopDirective = 311, + /** OpenMP compound root directive. + */ + CXCursor_OMPCompoundRootDirective = 312, + /** OpenACC Compute Construct. */ CXCursor_OpenACCComputeConstruct = 320, diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index e6fe46acb5fbc5..2881604ec781a3 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3026,6 +3026,9 @@ RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) { return TraverseOMPExecutableDirective(S); } +DEF_TRAVERSE_STMT(OMPCompoundRootDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPOpaqueBlockDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index 65434967142c84..4a3c2a53377d69 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -1560,6 +1560,66 @@ class OMPLoopDirective : public OMPLoopBasedDirective { } }; +/// This represents the root of the tree of broken-up compound directive. +/// It is used to implement pretty-printing consistent with the original +/// source. This is a pass-through directive for the purposes of semantic +/// analysis and code generation. +/// The getDirectiveKind() will return the id of the original, compound +/// directive. The associated statement will be the outermost one of the +/// constituent directives. The associated statement is always present. +class OMPCompoundRootDirective final : public OMPExecutableDirective { + friend class ASTStmtReader; + friend class OMPExecutableDirective; + + /// Build directive with the given start and end location. + /// + /// \param DKind The OpenMP directive kind. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// + OMPCompoundRootDirective(OpenMPDirectiveKind DKind, SourceLocation StartLoc, + SourceLocation EndLoc) + : OMPExecutableDirective(OMPCompoundRootDirectiveClass, DKind, StartLoc, + EndLoc) {} + + /// Build an empty directive. + /// + /// \param Kind The OpenMP directive kind. + /// + explicit OMPCompoundRootDirective(OpenMPDirectiveKind DKind) + : OMPExecutableDirective(OMPCompoundRootDirectiveClass, DKind, + SourceLocation(), SourceLocation()) {} + +public: + /// Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param DKind The OpenMP directive kind. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + static OMPCompoundRootDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + OpenMPDirectiveKind DKind, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt); + + /// Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param DKind The OpenMP directive kind. + /// \param NumClauses Number of clauses. + /// + static OMPCompoundRootDirective * + CreateEmpty(const ASTContext &C, OpenMPDirectiveKind DKind, + unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPCompoundRootDirectiveClass; + } +}; + /// This represents any executable OpenMP directive that is not loop- /// associated (usually block-associated). class OMPOpaqueBlockDirective final : public OMPExecutableDirective { diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index 6606cce3ff0852..ea0fafb884cb44 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -366,6 +366,7 @@ class TextNodeDumper void VisitPragmaCommentDecl(const PragmaCommentDecl *D); void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D); void VisitOMPExecutableDirective(const OMPExecutableDirective *D); + void VisitOMPCompoundRootDirective(const OMPCompoundRootDirective *D); void VisitOMPOpaqueBlockDirective(const OMPOpaqueBlockDirective *D); void VisitOMPOpaqueLoopDirective(const OMPOpaqueLoopDirective *D); void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D); diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index da8c91043c814e..e365dea0dc6f14 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -225,6 +225,7 @@ def OMPExecutableDirective : StmtNode<Stmt, 1>; def OMPMetaDirective : StmtNode<OMPExecutableDirective>; def OMPLoopBasedDirective : StmtNode<OMPExecutableDirective, 1>; def OMPLoopDirective : StmtNode<OMPLoopBasedDirective, 1>; +def OMPCompoundRootDirective : StmtNode<OMPExecutableDirective>; def OMPOpaqueBlockDirective : StmtNode<OMPExecutableDirective>; def OMPOpaqueLoopDirective : StmtNode<OMPLoopDirective>; def OMPParallelDirective : StmtNode<OMPExecutableDirective>; diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h index 18103a72c9cd31..45ddde3e1ade9b 100644 --- a/clang/include/clang/Sema/SemaOpenMP.h +++ b/clang/include/clang/Sema/SemaOpenMP.h @@ -849,6 +849,12 @@ class SemaOpenMP : public SemaBase { ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, SourceRange SR); + StmtResult ActOnOpenMPCompoundRootDirective(OpenMPDirectiveKind DKind, + ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, + SourceLocation StartLoc, + SourceLocation EndLoc); + StmtResult ActOnOpenMPOpaqueBlockDirective( OpenMPDirectiveKind Kind, ArrayRef<OMPClause *> Clauses, Stmt *AStmt, OpenMPDirectiveKind CancelRegion, const DeclarationNameInfo &DirName, diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index ac332f69826357..fabe9b64cfa75e 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1904,6 +1904,7 @@ enum StmtCode { STMT_SEH_TRY, // SEHTryStmt // OpenMP directives + STMT_OMP_COMPOUND_ROOT_DIRECTIVE, STMT_OMP_OPAQUE_BLOCK_DIRECTIVE, STMT_OMP_OPAQUE_LOOP_DIRECTIVE, STMT_OMP_META_DIRECTIVE, diff --git a/clang/lib/AST/StmtOpenMP.cpp b/clang/lib/AST/StmtOpenMP.cpp index 3bd88acb9a3c6e..7550aca7929127 100644 --- a/clang/lib/AST/StmtOpenMP.cpp +++ b/clang/lib/AST/StmtOpenMP.cpp @@ -259,6 +259,21 @@ void OMPLoopDirective::setFinalsConditions(ArrayRef<Expr *> A) { llvm::copy(A, getFinalsConditions().begin()); } +OMPCompoundRootDirective *OMPCompoundRootDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + OpenMPDirectiveKind DKind, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt) { + return createDirective<OMPCompoundRootDirective>( + C, Clauses, AssociatedStmt, /*NumChildren=*/0, DKind, StartLoc, EndLoc); +} + +OMPCompoundRootDirective *OMPCompoundRootDirective::CreateEmpty( + const ASTContext &C, OpenMPDirectiveKind DKind, unsigned NumClauses, + EmptyShell) { + return createEmptyDirective<OMPCompoundRootDirective>( + C, NumClauses, /*HasAssociatedStmt=*/true, /*NumChildren=*/0, DKind); +} + OMPOpaqueBlockDirective *OMPOpaqueBlockDirective::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind DKind, ArrayRef<OMPClause *> Clauses, diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index cd4f91337ef42c..b756b1c47c6060 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -735,6 +735,12 @@ void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S, PrintStmt(S->getRawStmt()); } +void StmtPrinter::VisitOMPCompoundRootDirective( + OMPCompoundRootDirective *Node) { + OS << "OMPCompoundRootDirective\n"; + PrintStmt(Node, /*ForceNoStmt=*/false); +} + void StmtPrinter::VisitOMPOpaqueBlockDirective(OMPOpaqueBlockDirective *Node) { OpenMPDirectiveKind DKind = Node->getDirectiveKind(); bool ForceNoStmt = false; diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index a4f032c3f78c5f..8880a9e277db6a 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -967,6 +967,11 @@ StmtProfiler::VisitOMPExecutableDirective(const OMPExecutableDirective *S) { P.Visit(*I); } +void StmtProfiler::VisitOMPCompoundRootDirective( + const OMPCompoundRootDirective *S) { + VisitOMPExecutableDirective(S); +} + void StmtProfiler::VisitOMPOpaqueBlockDirective( const OMPOpaqueBlockDirective *S) { VisitOMPExecutableDirective(S); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 09d3802c5e06dc..d1378cba65d761 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -2372,6 +2372,13 @@ void TextNodeDumper::VisitOMPExecutableDirective( OS << " openmp_standalone_directive"; } +void TextNodeDumper::VisitOMPCompoundRootDirective( + const OMPCompoundRootDirective *D) { + VisitOMPExecutableDirective(D); + OpenMPDirectiveKind DKind = D->getDirectiveKind(); + OS << " '" << llvm::omp::getOpenMPDirectiveName(DKind) << '\''; +} + void TextNodeDumper::VisitOMPOpaqueBlockDirective( const OMPOpaqueBlockDirective *D) { VisitOMPExecutableDirective(D); diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 42e9490ebbaa6e..82781eae764ab1 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -204,6 +204,10 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) { case Stmt::SEHTryStmtClass: EmitSEHTryStmt(cast<SEHTryStmt>(*S)); break; + case Stmt::OMPCompoundRootDirectiveClass: + // Skip this node, go straight through to the associated statement. + EmitStmt(cast<OMPCompoundRootDirective>(*S).getAssociatedStmt(), Attrs); + break; case Stmt::OMPOpaqueBlockDirectiveClass: case Stmt::OMPOpaqueLoopDirectiveClass: // These are catch-all nodes for executable OpenMP directives in templates. diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 467eb89afba52f..b3743b8fd1c74c 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1452,6 +1452,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Stmt::OMPMaskedTaskLoopDirectiveClass: case Stmt::OMPMasterTaskLoopSimdDirectiveClass: case Stmt::OMPMaskedTaskLoopSimdDirectiveClass: + case Stmt::OMPCompoundRootDirectiveClass: case Stmt::OMPOpaqueBlockDirectiveClass: case Stmt::OMPOpaqueLoopDirectiveClass: case Stmt::OMPOrderedDirectiveClass: diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index fbed2952de3fb6..3a59839a0b1828 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -23309,6 +23309,13 @@ StmtResult SemaOpenMP::ActOnOpenMPScopeDirective(ArrayRef<OMPClause *> Clauses, static bool checkScanScope(Sema &S, Scope *CurrentS, SourceLocation Loc); +StmtResult SemaOpenMP::ActOnOpenMPCompoundRootDirective( + OpenMPDirectiveKind DKind, ArrayRef<OMPClause *> Clauses, Stmt *AStmt, + SourceLocation StartLoc, SourceLocation EndLoc) { + return OMPCompoundRootDirective::Create( + getASTContext(), StartLoc, EndLoc, DKind, Clauses, AStmt); +} + StmtResult SemaOpenMP::ActOnOpenMPOpaqueBlockDirective( OpenMPDirectiveKind DKind, ArrayRef<OMPClause *> Clauses, Stmt *AStmt, OpenMPDirectiveKind CancelRegion, const DeclarationNameInfo &DirName, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 3a496811676787..cefaa9bd716e98 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -9406,6 +9406,14 @@ StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective( D->getBeginLoc(), D->getEndLoc()); } +template <typename Derived> +StmtResult TreeTransform<Derived>::TransformOMPCompoundRootDirective( + OMPCompoundRootDirective *D) { + // This function should never be found in a template. Directive splitting + // only happens in non-template functions. + llvm_unreachable("TransformOMPCompoundRootDirective in a template"); +} + template <typename Derived> StmtResult TreeTransform<Derived>::TransformOMPOpaqueBlockDirective( OMPOpaqueBlockDirective *D) { diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 4585693953be4d..1754c2cd89cdd4 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2409,6 +2409,13 @@ void ASTStmtReader::VisitOMPLoopDirective(OMPLoopDirective *D) { VisitOMPLoopBasedDirective(D); } +void ASTStmtReader::VisitOMPCompoundRootDirective(OMPCompoundRootDirective *D) { + VisitStmt(D); + // The DKind was read in ReadStmtFromStream. + Record.skipInts(1); + VisitOMPExecutableDirective(D); +} + void ASTStmtReader::VisitOMPOpaqueBlockDirective(OMPOpaqueBlockDirective *D) { VisitStmt(D); // The DKind was read in ReadStmtFromStream. @@ -3513,6 +3520,14 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = OMPCanonicalLoop::createEmpty(Context); break; + case STMT_OMP_COMPOUND_ROOT_DIRECTIVE: { + unsigned DKind = Record[ASTStmtReader::NumStmtFields]; + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields + 1]; + S = OMPCompoundRootDirective::CreateEmpty( + Context, static_cast<OpenMPDirectiveKind>(DKind), NumClauses, Empty); + break; + } + case STMT_OMP_OPAQUE_BLOCK_DIRECTIVE: { unsigned DKind = Record[ASTStmtReader::NumStmtFields]; unsigned NumClauses = Record[ASTStmtReader::NumStmtFields + 1]; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 47968dd78454a4..ed31af10d7417d 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -2409,6 +2409,13 @@ void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) { VisitOMPLoopBasedDirective(D); } +void ASTStmtWriter::VisitOMPCompoundRootDirective(OMPCompoundRootDirective *D) { + VisitStmt(D); + Record.writeUInt32(static_cast<unsigned>(D->getDirectiveKind())); + VisitOMPExecutableDirective(D); + Code = serialization::STMT_OMP_COMPOUND_ROOT_DIRECTIVE; +} + void ASTStmtWriter::VisitOMPOpaqueBlockDirective(OMPOpaqueBlockDirective *D) { VisitStmt(D); Record.writeUInt32(static_cast<unsigned>(D->getDirectiveKind())); diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index b980d6d25f9a24..cd3b49749c4ce8 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1748,6 +1748,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::SEHLeaveStmtClass: case Stmt::SEHFinallyStmtClass: case Stmt::OMPCanonicalLoopClass: + case Stmt::OMPCompoundRootDirectiveClass: case Stmt::OMPOpaqueBlockDirectiveClass: case Stmt::OMPOpaqueLoopDirectiveClass: case Stmt::OMPParallelDirectiveClass: _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits